I was playing with Visual Studio and templates.
Consider this code
struct Foo
{
struct Bar
{
};
static const int Bar=42;
};
template<typename T>
void MyFunction()
{
typename T::Bar f;
}
int main()
{
MyFunction<Foo>();
return 0;
}
When I compile this is either Visual Studio 2008 and 11, I get the following error
error C2146: syntax error : missing ';' before identifier 'f'
Is Visual Studio correct in this regard ? Is the code violating any standards ?
If I change the code to
struct Foo
{
struct Bar
{
};
static const int Bar=42;
};
void SecondFunction( const int& )
{
}
template<typename T>
void MyFunction()
{
SecondFunction( T::Bar );
}
int main()
{
MyFunction<Foo>();
return 0;
}
it compiles without any warnings. In Foo::BLAH a member preferred over a type in case of conflicts ?
EDIT Tests on G++ 4.2.1
struct Foo
{
static const int Bar=42;
};
void SecondFunction(const int& x)
{
}
template<typename T>
void MyFunction()
{
int x = Foo::Bar;
}
int main()
{
MyFunction<Foo>();
return 0;
}
compiles OK.
struct Foo
{
static const int Bar=42;
};
void SecondFunction(const int& x)
{
}
template<typename T>
void MyFunction()
{
SecondFunction(T::Bar);
}
int main()
{
MyFunction<Foo>();
return 0;
}
Gives me these errors
Undefined symbols:
“Foo::Bar”, referenced from:
void MyFunction() in cck498aS.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
In C++, named entities fall into one of three distinct ontological tiers: values, types and templates.
If a dependent name is of an unknown tier, then you must tell the compiler what it is:
If you say nothing, it’s a value.
If you say
typename, it’s a type.If you say
template, it’s a template.So
T::Bar, being a dependent name inside theMyFunctiontemplate, is automatically assumed to refer to a value, hence theintmemberFoo::Bar. On the other hand, in the first example,typename T::Barindeed refers to the member typeFoo::Bar.