1

当我尝试调用Foo<T>::setValue涉及多个模板参数的成员函数版本时,有人会告诉我为什么编译器会标记错误,如下所示。

ideone

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

海合会错误:

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 提到的问题之外,您的第二个函数模板将 anint作为其第二个参数,并且您提供了一个类型。

通过将名称更改为setValue2每个@Jason 的帖子,然后将函数调用更改为:

f1.setValue2<Bar, 3>();        

我不确定您要使用第三个模板函数定义来完成什么。看来您应该只需要一个模板参数,因为 P::Type 也可以派生。

我还应该注意,您的类定义并不十分精确——类的模板参数是 a typename,但您传递Bar::TYPE的是一个enum类型。

于 2012-05-15T16:57:20.560 回答