Dain
Dain

Reputation: 53

I'm trying to make a string class with static memory array

This is just for fun, I know i can use the std and not reinvent the wheel, etc.

This is essentially my class:

template<size_t size>
class sstring {
public:
    char buffer[size];
};

I want to be able to use it like this:

sstring<> str1 = "My string";      // One possible way
sstring str2 = "My other string";  // Another possible way

But the closest i get is: sstring<n> str = { "..." };, I don't quite understand why it cannot infer the size by itself and I would like it to do so.

Without templates I get a bit closer: sstring str = { "..." };.

I realized it happens because that's how aggregate initialization works, so i tried with a public constructor, but lost the aggregate advantages.

Then tried to overload the = operator, but still get the aggregate construction syntax.

I want to keep my class as an aggregate type and be able to construct it as any of the 'possible' examples above.

I would also like to keep the template so i can provide the size in case i can't / don't want to provide the value immediately, but it's not necessary.

Upvotes: -1

Views: 83

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123450

Disclaimer: I missed the aggregate part of the question. I will leave this answer nevertheless as you might not be aware of CTAD.

If you write a constructor that accepts a reference to a c-string you can make use of Class template argument deduction:

#include <cstddef>
#include <algorithm>

template<size_t size>
class sstring {
public:
    sstring(const char (&b)[size]) {
        std::copy(b,b+size,buffer);
    }
    char buffer[size];
};

int main() {
    sstring foo = "asd";
}

Live Demo

The explicit deduction guide would be

template <size_t size>
sstring(const char (&b)[size]) -> sstring<size>;

I cannot completely explain why the constructor is needed. It has to do with array to pointer decay. Without the constructor you can get this though:

#include <cstddef>
#include <algorithm>

template<size_t size>
class sstring {
public:
    char buffer[size];
};

template<class... U >
sstring(U... ) -> sstring<1 + sizeof...(U)>;

int main() {
    sstring foo{'a','b','c'};
}

Inpsired from the deduction guide for std::array (https://en.cppreference.com/w/cpp/container/array/deduction_guides)

Upvotes: 2

Related Questions