问题
I have a strange compilation warning for the following code, with Visual C++ 2010:
#include <iostream>
class test
{
public:
template<class obj>
class inner
{
private:
// Line 11:
template<int index, bool unused = true> struct AttributeName;
private:
template<bool b>
struct AttributeName<0,b>
{
static inline const char* get()
{
return "prop";
}
};
public:
typedef AttributeName<0> propname;
};
typedef inner<test> description;
};
int main()
{
test t;
std::cout << test::description::propname::get(); // Line 32
return 0;
}
The warning:
file.cpp(11) : warning C4348: 'test::inner<obj>::AttributeName' : redefinition of default parameter : parameter 2 (with [ obj=test ])
file.cpp(11) : see declaration of 'test::inner<obj>::AttributeName' (with [ obj=test ])
file.cpp(32) : see reference to class template instantiation 'test::inner<obj>' being compiled (with [ obj=test ])
What I don't understand is that AttributeName
"redefinition" is at the same line than the definition... sounds like a bug
I noticed that making inner
a non-template class removes the warning. However, this is not an option since the real code is more complicated than this testcase and need to be templated.
Also, this code won't compile if warning are treated as errors...
It compiles without warnings on GCC.
Why msvc is outputing such warning and is there a workaround ?
edit
The following modification:
template<int index, bool unused = true> struct AttributeName {};
seems to erase the warning.
回答1:
This is mostly a guess, as this seems to solve(?) it:
template<int index, bool unused = true> struct AttributeName;
template<int index, bool unused> struct AttributeName
{
};
My guess is that the forward declaration is seen as both a declaration and a "definition" since it can't see anything else, hence it complains about the default being "redefined" even though it's the same line. Could be unintentional, although 2012 behaves the same.
来源:https://stackoverflow.com/questions/12656239/redefinition-of-default-template-parameter