1

Foo<T>::setValue以下に示すように、複数のテンプレート引数を含むメンバー関数のバージョンを呼び出そうとすると、コンパイラがエラーをフラグする理由を教えてください。

イデオンを見る

class Bar
{
public:
    enum TYPE{};
};

//////////////////////////////////////////////////////////////////////////////////////

template<typename T>
class Foo
{
public:
    template<typename P>
    void setValue1();

    template<typename P, int>
    void setValue2();

    template<typename P, typename P::TYPE>
    void setValue3();

private:
    T   m_value;
};

//////////////////////////////////////////////////////////////////////////////////////

template<typename T>
template<typename P>
void Foo<T>::setValue1()
{
}

template<typename T>
template<typename P, int>
void Foo<T>::setValue2()
{
}

template<typename T>
template<typename P, typename P::TYPE>
void Foo<T>::setValue3()
{
}

//////////////////////////////////////////////////////////////////////////////////////

int main()
{
    Foo<Bar::TYPE> f1;

    f1.setValue1<Bar>();                // Compiles
    f1.setValue2<Bar, int>();       // ERROR
    f1.setValue3<Bar, Bar::TYPE>(); // ERROR

    return EXIT_SUCCESS;
}

GCC エラー:

error: no matching function for call to ‘Foo<Bar::TYPE>::setValue2()’
error: no matching function for call to ‘Foo<Bar::TYPE>::setValue3()’

MSVC .NET 2008 エラー:

Test6.cpp(60) : error C2975: 'Foo<T>::setValue2' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression
        with
        [
            T=Bar::TYPE
        ]
        Test6.cpp(24) : see declaration of 'Foo<T>::setValue2'
        with
        [
            T=Bar::TYPE
        ]
Test6.cpp(61) : error C2975: 'Foo<T>::setValue3' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression
        with
        [
            T=Bar::TYPE
        ]
        Test6.cpp(27) : see declaration of 'Foo<T>::setValue3'
        with
        [
            T=Bar::TYPE
        ]   
4

2 に答える 2

2

テンプレート引数に基づいてC++で関数をオーバーロードすることはできません...関数引数のシグネチャに基づいてのみ関数をオーバーロードできます。

于 2012-05-15T16:33:11.600 に答える
2

@Jasonが言及した問題に加えて、2番目の関数テンプレートはint2番目の引数として を取り、タイプを提供しています。

setValue2これは、@Jason の投稿に従って名前を に変更し、関数呼び出しを次のように変更することで修正されました。

f1.setValue2<Bar, 3>();        

3 番目のテンプレート関数定義で何を達成しようとしているのかわかりません。P::Type も派生できるため、テンプレート引数は 1 つだけ必要なようです。

また、クラス定義が正確ではないことにも注意してください。クラスのテンプレート引数は aですが、型であるそれをtypename渡しています。Bar::TYPEenum

于 2012-05-15T16:57:20.560 に答える