为什么要将'<'作为'operator<'而不是标记来包围模板参数?
Why take '<' as 'operator<' rather than a mark to enclose the template argument?
我的C++代码如下:
//test.cpp
#include <iostream>
using namespace std;
template <int SIZE, class T>
struct A
{
void g(int x, const T& t)
{
t.f<SIZE>(x);
}
};
struct B
{
template <int SIZE>
void f(int x) const
{
cout << SIZE << ": " << x << endl;
}
};
int main(void)
{
A<3, B> a;
B b;
a.g(9, b);
return 0;
}
当我用g++(版本是4.8.2
)编译它时,我得到了一个令人惊讶的错误:
test.cpp: In instantiation of ‘void A<SIZE, T>::g(int, const T&) [with int SIZE = 3; T = B]’:
test.cpp:27:13: required from here
test.cpp:9:12: error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘int’ to binary ‘operator<’
t.f<SIZE>(x);
^
为什么它将<
作为operator<
,而不是用一个标记来包围模板参数?
因为代码本身就不明确1,所以编译器必须决定哪种方式。C++标准委员会武断地决定,如果有疑问,假设名称是一个变量,而不是类型。
如果你希望你的代码被解析为模板,你需要明确地说:
t.template f<SIZE>(x);
1在解析此代码时,t
的类型尚不清楚,因为它是一个模板。考虑以下类型:
struct T {
int f;
};
如果您现在用该类型实例化A
,您将得到(由于模板已实例化,因此为伪代码):
void A<3, T>::g(int x, T const& t) {
((t.f) < 3) > x;
}
我添加了括号来澄清:编译器就是这样看待代码的,它是完全有效的(尽管毫无意义)。
让我们看看:
t.f < SIZE > (x);
留白并不重要。如果t.f
是一个变量,这可以说:做t.f < SIZE
,然后做(那个结果)> x
。
此外,编译器还不知道t.f
是一个变量还是一个函数模板。记住,模板可以是专门化的,所以即使现在看起来t.f
是一个函数模板;在这篇文章的后面,这个代码可以从B
的特殊化中实例化,其中t.f
是一个变量。
为了解决这个难题,除非您明确指出它们是其他名称,否则不明确的名称将被视为变量名称。在这种情况下,这是通过编写t.template f
来完成的;类似的原理使我们在CCD_ 15是从属名称时编写CCD_。
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- 有没有办法制作一个 c++ 宏(或类似的东西),它使用户语句被 while 循环的预定义函数包围?
- 用括号包围的实例的销毁
- 如何显式调用运算符<<
- 模板操作员&lt;未打电话
- C / CUDA中的模板方法是3个角括号(&lt;&lt;&lt;)
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 错误:调用"std::vector<:vector<int>>::p ush_back(std::vector<std::__cxx11::basic_string<
- C 建造者Clang STD :: Sill,找不到超载的操作员&lt;
- 如果您知道 1 的位置,请查找被 1 包围的零数
- 为什么STD :: MAP需要操作员&lt;以及我如何写一个
- 为什么“操作员”需要const但不是为“运营商&lt;”
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 左角支架解释为操作员&lt;而不是模板参数