模板化成员函数的语法
考虑以下代码:
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
放在自己的行上具有相同的效果吗?还是有一些我不知道的细微差别......?
(另外,如果有人能想到更好的标题,请告诉我。)
Consider the following code:
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)
{
// ...
}
The implementation for the second member function, doTemplateStuff
, will not compile if I condense it like this:
template <typename Datatype, typename AnotherDatatype>
void MyClass<Datatype>::doTemplateStuff(AnotherDatatype Argument)
{
// ...
}
Why is this? Shouldn't separating template information by commas have the same effect as putting each typename
on its own line? Or is there some subtle difference I'm not aware of...?
(Also, if someone can think of a better title please let me know.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个很好的问题。我不知道标准委员会决定这样设计模板的具体原因,但我认为这是对 lambda 演算和类型理论的回调。从数学上来说,任何接受两个参数并返回一个值的函数与接受一个参数然后返回一个接受另一个参数然后返回一个值的函数之间存在同构。例如:
λx。 λy。 x + y
同构(但不相同)
与λ(x, y) 。 x + y
其中 (x, y) 是表示 x 和 y 对的单个对象。
对于 C++ 成员函数模板,C++ 选择使用第一个系统。您必须指定最外层函数的所有参数,然后分别指定最内层函数的所有参数。从数学上讲,这相当于在一个参数列表中同时指定所有参数,但 C++ 没有选择这样做。
现在,一个非常好的问题是他们为什么不这样做。我不完全确定其基本原理,但如果我不得不猜测,这是因为与模板专业化的奇怪交互。如果我能想到一些具体的东西,我会更新这篇文章。
This is an excellent question. I don't know the specific reason that the standards committee decided to design templates this way, but I think it's a callback to lambda calculus and type theory. Mathematically speaking, there is an isomorphism between any function that takes two arguments and returns a value and a function that takes in a single argument, then returns a function that takes in yet another argument and then returns a value. For example:
λx. λy. x + y
is isomorphic with (but not identical to)
λ(x, y). x + y
where (x, y) is a single object representing the pair of x and y.
With C++ member function templates, C++ chose to use the first of these systems. You have to specify all the arguments for the outermost function, then, separately, all of the arguments for the innermost function. Mathematically this is equivalent to specifying all of the arguments at the same time in one argument list, but C++ didn't choose to do this.
Now, a really good question is why they didn't do this. I'm not fully sure of the rationale, but if I had to guess it's because of weird interactions with template specialization. If I can think of something specific I'll update this post.
在模板声明之间放置逗号告诉编译器需要两个模板参数。在您的情况下,因为当您像您一样声明函数时该对象是模板对象,所以您违反了自己的声明。它在
MyClass
对象中查找第二个模板,引用实际的类声明并意识到这是一个错误。因此,
这就是它所期望看到的。
是一个错误。它想知道其他模板参数来自哪里。
如果你想这样做,你需要在那里编写函数:
Putting comma's between the template declaration tells the compiler to expect two template parameters. In your case, because the object is a template object when you declare the function as you do you're violating your own declaration. It's looking for that second template in the
MyClass
object, referencing the actual class declaration and realizing that it's an error.Hence,
is what it's expecting to see.
is an error. It's wondering where that other template parameter came from.
If you want to do this you'll need to write the function right there: