8

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 {};

警告を消すようです。

4

1 に答える 1

8

これで解決(?)するように見えるので、これはほとんど推測です。

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

私の推測では、前方宣言は他に何も見えないため、宣言と「定義」の両方と見なされているため、同じ行であってもデフォルトが「再定義」されていると不平を言っています。2012 も同じように動作しますが、意図的ではない可能性があります。

于 2012-09-29T21:09:51.913 に答える