考虑以下类别:

class MyClass
{
    int _id;
public:
    decltype(_id) getId();
};

decltype(MyClass::_id) MyClass::getId()
{
    return _id;
}

它编译良好。

但是,当我用它制作一个模板类时:
template <class T>
class MyClass
{
    int _id;
public:
    decltype(_id) getId();
};

template <class T>
decltype(MyClass<T>::_id) MyClass<T>::getId()
{
    return _id;
}

我得到:
test.cpp:10:27: error: prototype for 'decltype (MyClass<T>::_id) MyClass<T>::getId()' does not match any in class 'MyClass<T>'
 decltype(MyClass<T>::_id) MyClass<T>::getId()
                           ^
test.cpp:6:19: error: candidate is: decltype (((MyClass<T>*)(void)0)->MyClass<T>::_id) MyClass<T>::getId()
     decltype(_id) getId();
                   ^

这是为什么?
为什么类型不同
  • decltype (MyClass<T>::_id) MyClass<T>::getId()
  • decltype (((MyClass<T>*)(void)0)->MyClass<T>::_id)

  • 我可以通过在类中定义主体来修复它:
    template <class T>
    class MyClass
    {
        int _id;
    public:
        decltype(_id) getId() { return _id; }
    };
    

    尾随返回类型遇到类似的问题:
    template <class T>
    class MyClass
    {
        int _id;
    public:
        auto getId() -> decltype(_id);
    };
    
    template <class T>
    auto MyClass<T>::getId() -> decltype(MyClass<T>::_id)
    {
        return _id;
    }
    

    错误:
    test.cpp:10:6: error: prototype for 'decltype (MyClass<T>::_id) MyClass<T>::getId()' does not match any in class 'MyClass<T>'
     auto MyClass<T>::getId() -> decltype(MyClass<T>::_id)
          ^
    test.cpp:6:10: error: candidate is: decltype (((MyClass<T>*)this)->MyClass<T>::_id) MyClass<T>::getId()
         auto getId() -> decltype(_id);
              ^
    
  • decltype (MyClass<T>::_id) MyClass<T>::getId()
  • decltype (((MyClass<T>*)this)->MyClass<T>::_id) MyClass<T>::getId()

  • g++ 5.3.0

    最佳答案

    根据标准草案N4582§5.1.1/p13 General [expr.prim.general](重点矿):



    同样来自第7.1.6.2/p4节,简单类型说明符[dcl.type.simple]( Emphasis Mine ):



    因此,由于decltype是未评估的操作数,因此该代码是合法的并且应该编译。

    一种干净的解决方法是使用decltype(auto):

    template<typename T>
    class MyClass {
      int _id;
    public:
      decltype(auto) getId();
    };
    
    template<typename T>
    decltype(auto) MyClass<T>::getId() {
      return _id;
    }
    

    上面的代码被GCC/CLANG/VC++接受。

    关于c++ - 原型(prototype)与decltype和auto不匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37185803/

    10-15 16:17