Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.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++ VS2010中反复出现的模板模式错误?_C++_Visual Studio 2010_Crtp - Fatal编程技术网

C++ VS2010中反复出现的模板模式错误?

C++ VS2010中反复出现的模板模式错误?,c++,visual-studio-2010,crtp,C++,Visual Studio 2010,Crtp,为什么这段代码不能在VS2010中编译 struct Base { void foo0() { } }; template<typename BASE> struct Derived : BASE { void foo1() { foo0(); } }; int main() { Derived<Base> ddd; ddd.foo1(); return 0; } struct Base { void foo0(){} };

为什么这段代码不能在VS2010中编译

struct Base
{
    void foo0() { }
};
template<typename BASE> struct Derived : BASE
{
    void foo1() { foo0(); }
};
int main()
{
    Derived<Base> ddd;
    ddd.foo1();
    return 0;   
}
struct Base
{
void foo0(){}
};
派生的模板结构:基
{
void foo1(){foo0();}
};
int main()
{
衍生ddd;
ddd.foo1();
返回0;
}

它在其他编译器中编译得很好。如果我在下面的帮助下调用foo0,它也会编译:this->foo0()

我刚刚发现这种行为背后的原因是语言扩展编译器选项(/Za)。所以,如果禁用语言扩展,上述代码将无法编译。这里奇怪的是,这必须是C++语言的一部分,而不是MS语言扩展。
希望这对某人有所帮助…

在声明
派生::foo1()
时,它不知道
基是什么。然后它试图找出什么是
foo0
。视图中没有
foo0
——或者更糟的是,它会找到一个要调用的全局
foo0
。这是一个错误


当您改为调用
this->foo0()
时,您会通知编译器您希望将其作为一种方法来查找。

这不是奇怪的重复模板模式。。。CRTP以另一种方式工作:从基类调用派生方法。众所周知,MSVC编译的代码不符合标准,我非常确定这段代码将在较旧的版本上编译。我猜微软最终改进了他们的编译器,使之成为标准指令,他们可能将旧的行为作为“扩展”包含进来,以允许旧的代码进行编译。你必须用这个->或BASE来限定Foe0::对于你的代码,遵从C++标准。托梅克,你把你的评论放在CRTP的这个特定的情况下,或者这也适用于任何基础派生的对(即使没有涉及模板)。有一个不明确的标准和/或强迫你总是合格,这似乎很奇怪。这将使继承无效,或使此->成为必需的,以获得一致的代码。人们会认为C++会演变成易于开发人员使用,而不是编译器编译代码的容易。谢谢您的回复。我不记得确切的措辞,但很快,您需要限定所有继承的名称,这些名称来自依赖于模板参数的基类。正如Yakk提到的,编译器在解析模板时无法知道foo0是派生的,因为它还没有看到基类。因此,它会将foo0视为属于封闭命名空间,如果未声明它,则会抛出一个错误。在启用扩展时,clang或ms似乎不需要这种类型的显式限定,因此编译器必须很容易对其进行排序。如果该语言支持这种类型的CRTP,那么他们应该确保对BASE的隐式访问也在标准中。这只会让生活更轻松:)不过谢谢你的评论。