Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 混淆模板错误_C++_Templates_Llvm_Clang - Fatal编程技术网

C++ 混淆模板错误

C++ 混淆模板错误,c++,templates,llvm,clang,C++,Templates,Llvm,Clang,我已经玩了一会儿clang,我偶然发现了“test/SemaTemplate/dependent template recover.cpp”(在clang发行版中),它应该提供从模板错误中恢复的提示 整个过程可以很容易地简化为一个简单的例子: template<typename T, typename U, int N> struct X { void f(T* t) { // expected-error{{use 'template' keywor

我已经玩了一会儿clang,我偶然发现了“test/SemaTemplate/dependent template recover.cpp”(在clang发行版中),它应该提供从模板错误中恢复的提示

整个过程可以很容易地简化为一个简单的例子:

template<typename T, typename U, int N> struct X {
    void f(T* t)
    {
        // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
        t->f0<U>();
    }
};
模板结构X{
空隙f(T*T)
{
//预期错误{使用'template'关键字将'f0'视为依赖模板名称}
t->f0();
}
};
clang生成的错误消息:

tpl.cpp:6:13: error: use 'template' keyword to treat 'f0' as a dependent template name
         t->f0<U>();
            ^
            template 
1 error generated.
tpl.cpp:6:13:错误:使用'template'关键字将'f0'视为从属模板名称
t->f0();
^
模板
生成1个错误。

。。。但是我很难理解到底应该在哪里插入
模板
关键字才能使代码语法正确?

在插入符号的位置之前插入它:

template<typename T, typename U, int N> struct X {
     void f(T* t)
     {
        t->template f0<U>();
     }
};
模板结构X{
空隙f(T*T)
{
t->template f0();
}
};
编辑:如果你像一个编译器一样思考,那么这个规则的原因就会变得更清楚。编译器通常一次只向前看一个或两个标记,通常不“向前看”表达式的其余部分。[编辑:请参阅注释]使用关键字的原因与使用
typename
关键字指示依赖类型名称的原因相同:它告诉编译器“嘿,您将看到的标识符是模板的名称,而不是后跟小于号的静态数据成员的名称。”

摘自

.template构造 在引入类型名后发现了一个非常类似的问题。考虑下面的例子,使用标准的位集类型:

template<int N> 
void printBitset (std::bitset<N> const& bs) 
{ 
    std::cout << bs.template to_string<char,char_traits<char>, 
                                       allocator<char> >(); 
} 
模板
无效打印位集(标准::位集常量和二进制)
{ 
标准::coutISO C++03 14.2/4:

当成员模板专用化的名称出现在后缀表达式中的.or->之后,或在限定id中的嵌套名称说明符之后,并且后缀表达式或限定id显式依赖于模板参数时(14.6.2),成员模板名称的前缀必须为关键字template。否则,将假定该名称为非模板名称

t->f0();
f0
中,是出现在
->
之后的成员模板专门化,它显式地依赖于模板参数
U
,因此成员模板专门化必须以
template
关键字作为前缀


因此,将
t->f0()
更改为
t->template f0()

除了其他人提出的观点之外,请注意,有时编译器无法下定决心,两种解释都可以在实例化时生成有效的替代程序

#include <iostream>

template<typename T>
struct A {
  typedef int R();

  template<typename U>
  static U *f(int) { 
    return 0; 
  }

  static int f() { 
    return 0;
  }
};

template<typename T>
bool g() {
  A<T> a;
  return !(typename A<T>::R*)a.f<int()>(0);
}


int main() {
  std::cout << g<void>() << std::endl;
}
#包括
模板
结构A{
typedef int R();
模板
静态U*f(int){
返回0;
}
静态int f(){
返回0;
}
};
模板
布尔g(){
A A;
return!(typename A::R*)A.f(0);
}
int main(){

STD::我从来没能猜到……但是谢谢你!-)显然有关于C++的东西,即使无限的前瞻性,你仍然需要<代码>模板<代码>。有和没有<代码>模板< /代码>的情况下,会产生不同行为的有效程序。所以这不仅仅是一个合成程序。cal问题(
t->f0(0)
在语法上对小于和模板参数列表版本都有效)@Johannes Schaub-litb:是的,因此与其说是向前看,不如说是给表达式赋予一致的语义。你试过把它插入箭头指向的地方吗?类似而且有趣的是,我想把表达式放在括号里:
t->(f0())将修正,正如我认为将 f0()>代码>成单独的表达式……嗯,我想错了,看来……你能评论一下为什么会这样吗?为什么C++需要这种语法?是的,这很奇怪。语言可以“检测”。模板关键字需要存在。如果可以,则只需“插入”关键字本身就在那里。这是一个可怕的例子!我无法重现您在Visual Studio 2013中描述的行为。它总是调用
f
,并且总是打印
1
,这对我来说非常有意义。我仍然不明白为什么需要
模板
关键字,以及它有什么区别。@Violet the VSC++编译器不是一个兼容的C++编译器。如果你想知道为什么VSC++总是打印1个,那么就需要一个新的问题。这个答案解释了为什么需要代码>模板/>代码:不依赖于标准的术语,它很难理解。如果这个答案中的任何东西仍然令人困惑,请报告。@谢谢。呃。原来,我以前读过它,因为它已经被我提升了。显然,我的记忆是meh。