C++ 为什么主表达式不';不包括模板id
我有这样的代码,用“g++-Wall-g-std=c++11 test.cpp”编译,它没有编译,因为错误:在“')”标记之前应该有主表达式C++ 为什么主表达式不';不包括模板id,c++,bnf,C++,Bnf,我有这样的代码,用“g++-Wall-g-std=c++11 test.cpp”编译,它没有编译,因为错误:在“')”标记之前应该有主表达式 #包括 #包括 #包括 int main() { std::vec; 对于(int i=0;i老实说,我没有从表达式的角度考虑这一点。但是我的思考方式-std::sort需要一个对象作为它的第三个参数。std::less只是一个类型声明。std::less()创建std::sort所需的对象。这是语法分析器和语义分析器之间的区别。C++的语法只告诉您什么是
#包括
#包括
#包括
int main()
{
std::vec;
对于(int i=0;i老实说,我没有从表达式的角度考虑这一点。但是我的思考方式-std::sort
需要一个对象作为它的第三个参数。std::less
只是一个类型声明。std::less()
创建std::sort
所需的对象。这是语法分析器和语义分析器之间的区别。C++的语法只告诉您什么是语法的——什么将通过语法分析器。例如,语法还允许您执行以下操作:
std::sort(vec.begin(), vec.end(), ~MyClass);
出于同样的原因——因为~类名
是一个非限定id
。您需要查看语言的语义规则,以确定程序是否格式正确,而不仅仅是查看语法,并且语言的语义规则需要此处的值,而不是类型
具体来说,我相信标准是通过C++11 5.2.2[expr.call]/4中函数调用操作符(()
)的规则来说明这一点的:(强调我的)
调用函数时,应使用相应的参数初始化每个参数(8.3.5)(8.5,12.8,12.1)
8.5[dcl.init]/1:(强调矿山)
声明符可以为声明的标识符指定初始值。该标识符指定正在初始化的变量
但我不是标准学者,也不是委员会成员,因此语法正确并不一定会使程序语义正确。primary expression->template id的语法产品允许将函数模板的特殊化用作表达式,例如,这是有效的:
template <typename T>
bool less(const T& a, const T& b) { return a < b; }
int main() {
std::vector<int> vec;
std::sort(vec.begin(), vec.end(), less<int>);
}
模板
bool-less(常数T&a,常数T&b){返回a
但是,引用类模板的模板id不能用作表达式。您使用的是哪种编译器?FWIW,Clang:error:expected'('对于函数样式转换或类型construction@MantoshKumar,可能是GCC.4.9给出了错误。看来编译错误消息中有问题。我在VS2010中运行了相同的程序,得到了以下“错误C2275:'std::less':非法使用此类型作为表达式”@MantoshKumar,这个铿锵错误没有错。它基本上是说“你有一半这种类型的表达式,但你缺少了另一半”+ 1。语义和语法的差别在最好的时候是微妙的,在C++中更是如此。标准没有区分不同格式的不完善的程序:它只是定义了一个格式良好的程序,作为一个“根据语法规则、可诊断语义规则和一个定义规则构造的C++程序”。,而一个格式不正确的程序则是一个格式不正确的程序。@Casey。我几乎同意你的看法。我认为该程序在语义上是错误的,但它确实是一个主表达式,那么这是否意味着g++报告了一个错误类型的错误?看来clang的错误代码“非法使用此类型作为表达式”更为合理。
std::sort(vec.begin(), vec.end(), ~MyClass);
template <typename T>
bool less(const T& a, const T& b) { return a < b; }
int main() {
std::vector<int> vec;
std::sort(vec.begin(), vec.end(), less<int>);
}