C ++ 11 MSVS vs GCC template parameter name visibility when initializing static member
I just want to ask why MSVS2013 is complaining about this code as opposed to GCC (4.8.3 at least):
template <typename T>
struct MyClass
{
typedef std::function<T*()> FunctionType;
static FunctionType funcObj;
};
template <typename T> typename MyClass<T>::FunctionType MyClass<T>::funcObj =
[]{return new T();};
In msvs2013 it complains about this: Error 1 error C2061: Syntax error: identifier 'T'
And to fix I have to change it to this:
template <typename T>
struct MyClass
{
typedef std::function<T*()> FunctionType;
static FunctionType funcObj;
static T* foo()
{
return new T();
}
};
template <typename T> typename MyClass<T>::FunctionType MyClass<T>::funcObj =
MyClass<T>::foo;
NOTE: "MyClass <T> :: 'is not required on the last line. I just want to say that T can still be used on the right side of the operation (to be assigned), and when T is inside a lambda it is no longer usable use.
Which one complies with the current standard? Is there a way to ensure that the type name can still be used in the lambda in such cases?
Thank you in advance!
Edit
The problem seems to be fixed in the current version, so the first version also works in MSVS.
source to share
MSVC is not standard as the standard says (ยง9.4.2 [class.static.data]):
The initialization expression in the definition of a static item is in the scope of its class
Obviously, the template parameter T
is in the scope of the template class, so its name must be available in the static member initializer funcObj
. Lambdas inherits enclosing scope types, so this version conforms to the standard:
template <typename T> typename MyClass<T>::FunctionType MyClass<T>::funcObj =
[]{return new T();};
source to share