【问题标题】:Syntax for Templated Member Functions模板化成员函数的语法
【发布时间】:2011-01-19 03:07:08
【问题描述】:

考虑以下代码:

template <typename Datatype>
class MyClass
{
    void doStuff();

    template <typename AnotherDatatype>
    void doTemplateStuff(AnotherDatatype Argument);
};

template <typename Datatype>
void MyClass<Datatype>::doStuff()
{
    // ...
}

template <typename Datatype>
template <typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
    // ...
}

如果我这样压缩第二个成员函数doTemplateStuff,则无法编译:

template <typename Datatype, typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
    // ...
}

这是为什么?用逗号分隔模板信息不应该与将每个 typename 放在自己的行上具有相同的效果吗?还是有一些我不知道的细微差别...?

(另外,如果有人能想到更好的标题,请告诉我。)

【问题讨论】:

    标签: c++ templates class syntax


    【解决方案1】:

    这是一个很好的问题。我不知道标准委员会决定以这种方式设计模板的具体原因,但我认为这是对 lambda 演算和类型理论的回调。从数学上讲,任何接受两个参数并返回一个值的函数与一个接受一个参数,然后返回一个接受另一个参数然后返回一个值的函数之间存在同构。例如:

    λx。 λy。 x + y

    与(但不等同于)同构

    λ(x, y)。 x + y

    其中 (x, y) 是表示 x 和 y 对的单个对象。

    对于 C++ 成员函数模板,C++ 选择使用这些系统中的第一个。您必须指定最外层函数的所有参数,然后分别指定最内层函数的所有参数。从数学上讲,这相当于在一个参数列表中同时指定所有参数,但 C++ 没有选择这样做。

    现在,一个非常好的问题是为什么他们没有这样做。我不完全确定基本原理,但如果我不得不猜测这是因为与模板专业化的奇怪交互。如果我能想到一些具体的事情,我会更新这篇文章。

    【讨论】:

    【解决方案2】:

    在模板声明之间放置逗号告诉编译器需要两个模板参数。在您的情况下,因为当您声明函数时对象是模板对象,所以您违反了自己的声明。它在 MyClass 对象中寻找第二个模板,引用实际的类声明并意识到这是一个错误。

    因此,

    template<typename T, typename V>
    struct Foo{
        void bar();
    };
    
    template<typename T, typename V>
    void Foo<T,V>::bar(){...}
    

    是它期望看到的。

    template<typename T>
    struct Foo{
        void bar();
    }
    
    template<typename T, typename V>
    void Foo<T>::bar(){...}
    

    是一个错误。它想知道其他模板参数是从哪里来的。

    如果你想这样做,你需要在那里编写函数:

    template<typename T>
    struct Foo{
        template<typename V>
        void bar(const V& _anInputValue){
            cout << _anInputValue;
        }
    
        void baz();
    };
    
    template<typename T>
    void Foo<T>::baz(){
        cout << "Another function.";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多