C++ 模板成员函数的语法
考虑以下代码:C++ 模板成员函数的语法,c++,templates,class,syntax,C++,Templates,Class,Syntax,考虑以下代码: template <typename Datatype> class MyClass { void doStuff(); template <typename AnotherDatatype> void doTemplateStuff(AnotherDatatype Argument); }; template <typename Datatype> void MyClass<Datatype>::doS
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)
{
// ...
}
为什么会这样?用逗号分隔模板信息是否应该与将每个typename
放在自己的行上具有相同的效果?还是有一些我不知道的细微差别
(另外,如果有人能想出一个更好的标题,请告诉我。)在模板声明之间加逗号告诉编译器需要两个模板参数。在您的情况下,因为当您像这样声明函数时,对象是一个模板对象,所以您违反了自己的声明。它在
MyClass
对象中寻找第二个模板,引用实际的类声明并意识到这是一个错误
因此,
template<typename T, typename V>
struct Foo{
void bar();
};
template<typename T, typename V>
void Foo<T,V>::bar(){...}
模板
结构Foo{
空心钢筋();
};
模板
void Foo::bar(){…}
这就是它期待看到的
template<typename T>
struct Foo{
void bar();
}
template<typename T, typename V>
void Foo<T>::bar(){...}
模板
结构Foo{
空心钢筋();
}
模板
void Foo::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.";
}
模板
结构Foo{
模板
空栏(常数V和输入值){
这是一个很好的问题。我不知道标准委员会决定以这种方式设计模板的具体原因,但我认为这是对lambda演算和类型理论的回调。从数学上讲,任何接受两个参数并返回一个值的函数和接受一个值的函数之间都存在同构一个参数,然后返回一个函数,该函数接受另一个参数,然后返回一个值。例如:
λx.λy.x+y
同构于(但不等同于)
λ(x,y).x+y
其中(x,y)是表示x和y对的单个对象
使用C++成员函数模板,C++选择使用这些系统中的第一个。必须为最外函数指定所有参数,然后分别指定最内层函数的所有参数。数学上,这等同于在一个参数列表中同时指定所有参数,但C++没有选择。这样做
现在,一个非常好的问题是他们为什么不这样做。我不完全确定其原理,但如果我不得不猜测这是因为与模板专门化的奇怪交互。如果我能想到一些具体的东西,我将更新这篇文章。这种同构称为Currying(参见)例如,它是Haskell编程语言的基石之一。
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.";
}