У меня есть странное предупреждение компиляции для следующего кода с 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;
}
Предупреждение:
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 ])
Что я не понимаю, так это AttributeName
«переопределение» находится в той же строке, что и определение … звучит как ошибка
Я заметил, что делает inner
не шаблонный класс удаляет предупреждение. Однако это не вариант, так как реальный код более сложен, чем этот тестовый пример, и его необходимо шаблонизировать.
Кроме того, этот код не будет компилироваться, если предупреждение будет считаться ошибкой …
Он компилируется без предупреждения на GCC.
Почему msvc выводит такое предупреждение и есть ли обходной путь?
редактировать
Следующая модификация:
template<int index, bool unused = true> struct AttributeName {};
кажется, стереть предупреждение.
Это в основном предположение, так как это, кажется, решает (?) Это:
template<int index, bool unused = true> struct AttributeName;
template<int index, bool unused> struct AttributeName
{
};
Я предполагаю, что предварительное объявление рассматривается и как объявление, и как «определение», так как больше ничего не видит, поэтому жалуется на то, что значение по умолчанию «переопределено», даже если это одна и та же строка. Может быть непреднамеренным, хотя 2012 год ведет себя так же.
Других решений пока нет …