【问题标题】:"Redefinition" of default template parameter默认模板参数的“重新定义”
【发布时间】:2012-09-21 07:07:07
【问题描述】:

对于以下代码,使用 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 设为非模板类​​会删除警告。但是,这不是一个选项,因为实际代码比这个测试用例更复杂,需要模板化。

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

It compiles without warnings on GCC.

为什么 msvc 会输出这样的警告,是否有解决方法?

编辑

以下修改:

template<int index, bool unused = true> struct AttributeName {};

似乎消除了警告。

【问题讨论】:

  • 致反对者:请留言说明您反对的原因。
  • @PeterMortensen 不,真的不是骗子。您链接的问题是关于函数参数,而我的问题是关于模板参数。此外,我的是关于一个错误......

标签: c++ visual-studio templates default-parameters


【解决方案1】:

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

template<int index, bool unused = true> struct AttributeName;
template<int index, bool unused> struct AttributeName
{
};

我的猜测是,前向声明既被视为声明又被视为“定义”,因为它看不到其他任何内容,因此它抱怨默认值被“重新定义”,即使它是同一行。可能是无意的,尽管 2012 年表现相同。

【讨论】:

  • 这似乎很有可能。但是,我不是很理解“它看不到其他任何东西”
  • 我不得不承认,克里斯蒂安,在想出你所做的同样事情之前,我盯着这个推论看了一段时间。 ESP 之类的东西:test::description::propname::AttributeName::AttributeName::AttributeName::get() 完全符合这个定义。
  • 并且 fwiw 在 Mac 上的 llvm 编译器没有问题(希望 Mac gcc 编译器默认工作)。
  • Synxis,记住我不是 C++ 甚至 MSVC++ 专家。你的第 11 行是一个前向声明,你从来没有为它定义任何东西。然而,编译器实际上也不需要它的任何东西,除了知道它存在是因为你对其进行了专门化,所以通过编译器中的一些奇怪的巧合,它没有找到定义,回到声明,把它当作定义和数字“嘿,默认参数已经在声明中声明了,所以让我们警告一下”。就像把同一本书读了两遍,然后抱怨你已经知道了:-)
  • 可以确认这是一个错误
猜你喜欢
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多