CRTP失败w/decltype

Pup*_*ppy 5 c++ crtp decltype visual-c++ c++11

template<typename T> struct A {
    auto func() -> decltype(T::func()) {
        return T::func();
    }
};
class B : public A<B> {
    void func() {
    }
};
Run Code Online (Sandbox Code Playgroud)

对我来说似乎很简单.但是MSVC无法编译.

visual studio 2010\projects\temp\temp\main.cpp(4): error C2039: 'func' : is not a member of 'B'
visual studio 2010\projects\temp\temp\main.cpp(8) : see declaration of 'B'
visual studio 2010\projects\temp\temp\main.cpp(8) : see reference to class template instantiation 'A<T>' being compiled
          with
          [
              T=B
          ]
visual studio 2010\projects\temp\temp\main.cpp(4): error C3861: 'func': identifier not found
Run Code Online (Sandbox Code Playgroud)

即使编译器很乐意接受调用该函数.下面的样本编译得很好.

template<typename T> struct A {
    void func() {
        return T::func();
    }
};
class B : public A<B> {
    void func() {
    }
};
Run Code Online (Sandbox Code Playgroud)

我试图使用模板参数中的任何类型都有同样的问题.

template<typename T> struct A {
    typedef typename T::something something;
};
class B : public A<B> {
    typedef char something;
};

visual studio 2010\projects\temp\temp\main.cpp(4): error C2039: 'something' : is not a member of 'B'
Run Code Online (Sandbox Code Playgroud)

而B类明确定义了一种称为"某事"的类型.编译器非常乐意在类型为T,T&或T*的对象上调用函数,但我似乎无法从T访问任何类型.

Joh*_*itb 3

您试图T::func在声明之前使用它。这就是编译器对你大喊大叫的原因。请注意,当您从类派生时,如果该类来自类模板,则会生成该类。并且类的隐式生成(称为隐式实例化)需要为其所有成员生成声明(因此编译器知道类的 sizeof 值,并可以对其进行查找)。

所以它也实例化了声明auto func() -> decltype(T::func())并且肯定会在这里失败。