默认模板参数的"重新定义"

Syn*_*xis 8 c++ templates visual-studio default-parameters

使用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;
}
Run Code Online (Sandbox Code Playgroud)

警告:

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 ])
Run Code Online (Sandbox Code Playgroud)

我不明白的是,AttributeName"重新定义"与定义在同一条线上...听起来像一个错误

我注意到制作inner非模板类会删除警告.但是,这不是一个选项,因为实际代码比这个测试用例更复杂,需要模板化.

此外,如果将警告视为错误,则此代码将无法编译...

它在没有GCC警告的情况下编译.

为什么msvc输出这样的警告并且有解决方法吗?

编辑

以下修改:

template<int index, bool unused = true> struct AttributeName {};
Run Code Online (Sandbox Code Playgroud)

似乎抹去了警告.

Chr*_*ber 8

这主要是猜测,因为这似乎解决了(?)它:

template<int index, bool unused = true> struct AttributeName;
template<int index, bool unused> struct AttributeName
{
};
Run Code Online (Sandbox Code Playgroud)

我的猜测是前向声明被视为声明和"定义",因为它看不到任何其他东西,因此它抱怨默认为"重新定义",即使它是同一行.可能是无心的,虽然2012年表现相同.

  • Synxis,请记住我不是C++甚至是MSVC++专家.你的第11行是一个前向声明,你永远不会为它定义任何东西.然而,编译器实际上并不需要任何东西,除了知道它存在因为你专门化它,所以通过编译器中的一些奇怪的巧合它找不到定义,回到声明处理它就像定义和数字"嘿,默认参数已在声明中声明,所以让我们警告".喜欢两次读同一本书,抱怨你已经知道了:-) (2认同)