0

I need a class which looks like this:

template<typename T, class S, size_t C>
class myClass
{
public:
    myClass(); // Ctor

    /*


    */
private:
S myData;
}

Where T is type of stored data, S is a container type and C is it's size. Methods won't depend on a container type, but I still need to properly initialize S. For example, let S be std::vector, I tried:

template<typename T, size_t C>
myClass<T, std::vector<T>, C>::myClass()
{

}

But I get E0040 expected identifier error.

Lenassa
  • 92
  • 7
  • 2
    Does this answer your question? [Template class with template container](https://stackoverflow.com/questions/16596422/template-class-with-template-container) – Tony Tannous May 24 '20 at 20:26
  • I don't think you can define individual members by specializing on the type like this... you'd need a template constructor _or_ you would need to create a specialization of `myClass`. – cdhowie May 24 '20 at 20:29
  • 1
    You cannot partial specialize method/function. – Jarod42 May 24 '20 at 20:42
  • @TonyTannous it says: "the number and type of arguments in the template template parameter declaration must match exactly the number and type of arguments in the definition of the corresponding class template you want to pass as a template argument". So, It would work for ```std::vector```, but won't for ```std::array```, am I right? UPD I forgot that ```std::vector``` has second parameter for allocator, so that might work, I'll try it now. – Lenassa May 24 '20 at 20:42
  • 1
    Can you use C++17? – Jarod42 May 24 '20 at 20:44
  • @Jarod42 Yes, I can. – Lenassa May 24 '20 at 20:45
  • 1
    Sorry I just noticed you tagged me with a question, and I see an answer already. Enjoy coding. – Tony Tannous May 24 '20 at 22:21

1 Answers1

1

You cannot partial specialize a method, you could partial specialize the whole class, but require some duplication.

As you can use C++17, you might tweak the implementation instead:

template<typename T, class S, size_t C>
myClass<T, S, C>::myClass()
{
    if constexpr (std::is_same_v<S, std::vector<T>>) {
        // special case
    } else {
        // regular case
    }
}

tag dipatching in another option (pre-C++17) which has the advantage to allow member initializer list:

template <typename T> struct tag{}; 

template <typename T, class S, size_t C>
class myClass
{
private:
    myClass(tag<std::vector<T>>) : myData(/*special case */) {/* special case */}

    template <typename U>
    myClass(tag<U>) : myData(/*regular case */) {/* regular case */}

public:
    myClass() : myClass(tag<S>{}) {}

private:
    S myData;
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • While you cannot specialize a method, it can use a specialized class... – Phil1970 May 24 '20 at 20:56
  • 1
    @Phil1970: C++ doesn't allow **partial** specialization for function/method (function/method have overloads, class has not). Full specialization is allowed though. – Jarod42 May 24 '20 at 21:04
  • Is it possible to make it work with ```std::array``` somehow? – Lenassa May 24 '20 at 21:15
  • 1
    Yes, `template myClass(tag>)`. – Jarod42 May 24 '20 at 21:25
  • So, I tried to create an instance of ```myClass```:```myClass, 10> a;```, but it produces ```C2079: myData uses structure without definition``` error (my IDE's locale isn't English, so this translation might be off). – Lenassa May 24 '20 at 21:44
  • 1
    @Lenassa: Work as expected [here](https://coliru.stacked-crooked.com/a/512e749a82f3d7ea). – Jarod42 May 24 '20 at 21:51
  • I guess it has to be something with project settings, since it works in a fresh one and on an online version of my compiler, but I'm sure it won't be a problem to fix. Thank you very much for you help. – Lenassa May 24 '20 at 22:08