-1

I have an existing struct as follows:

template<typename T>
struct Foo
{
    T bar;

    Foo() {}

    Foo(T bar) : bar(bar) {}
};

How do I provide a specialization so that T bar is set to a value? I attempted to use the methods outlined in this question by using the following:

template<>
Foo<ClassA>::bar = nullptr;

But this gave the following errors in Visual Studio 2015:

Foo:-

this declaration has no storage class or type specifier

bar:-

ClassA Foo::bar [with T=ClassA]" is not an entity that can be explicitly specialized

Community
  • 1
  • 1
Class Skeleton
  • 2,913
  • 6
  • 31
  • 51
  • additionaly `bar` is not a static member of any `Foo` – BeyelerStudios Aug 18 '15 at 15:20
  • 1
    Why are you using the word "specialization"? This isn't specialization. Actually, perhaps we should remove the work specialization from this question (after we are sure we know what the OP is trying to do.) – Aaron McDaid Aug 18 '15 at 16:26
  • 2
    Can you confirm that you are asking about *initialization*? You want to ensure that, when somebodys constructs a `Foo` that the data members are initialized correctly during the construction? – Aaron McDaid Aug 18 '15 at 16:38
  • @AaronMcDaid - Yes, this is in fact for initialization. I have updated the question title – Class Skeleton Aug 19 '15 at 11:39

2 Answers2

1
template<>
Foo<ClassA>::bar = nullptr;

That kind of specialization only works for static members. You want to set the value during construction. You could give your class a static variable to use as a default for bar and specialize that instead:

template<typename T>
struct Foo
{
    static T barDefault;

    T bar;

    Foo(T bar=barDefault) : bar(bar) {}
};

template <typename T>
T Foo<T>::barDefault = T{};

template<>
ClassA Foo<ClassA>::barDefault = nullptr;
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
1

I see the following issues with your code.

  1. You don't have the type specifier in the line

    template<>
    Foo<ClassA>::bar = nullptr;
    
  2. Even when you add a type specifier, such as:

    template<>
    ClassA* Foo<ClassA>::bar = nullptr;
    

    the code is not legal. You cannot specialize a non-static member variable. You can specialize member functions and static member variables only.

The following is legal.

template<typename T>
struct Foo
{
    T bar;
    static T bar2;

    Foo() {}

    Foo(T bar) : bar(bar) {}
};


struct ClassA {};

// Definition of Foo<T>::bar2 for most types.
template <typename T>
T Foo<T>::bar2 = {};

// Definition of Foo<T>::bar2 for T=ClassA.
template <>
ClassA Foo<ClassA>::bar2 = {};

The link you referenced in the question talks about specializing member functions, not member variables.

R Sahu
  • 204,454
  • 14
  • 159
  • 270