当前位置:  开发笔记 > 编程语言 > 正文

在C++ 11中确定泛型返回类型时出错

如何解决《在C++11中确定泛型返回类型时出错》经验,为你挑选了1个好方法。

在C++ 14应用程序的上下文中,我使用了一个可以恢复如下的方案(最小可重复性测试):

template 
struct LocateFunctions {    
  auto get_it() const // <-- here is the problem
  {
    auto ret = typename Container::Iterator();
    return ret;
  }
};

template 
struct A : public LocateFunctions> {    
  struct Iterator {};
};

int main() {  
  A a;
}

这种方法在C++ 14中使用GCC和Clang编译器进行编译和运行.

现在我想将我的应用程序迁移到Windows,为此我正在使用MinGW.不幸的是,它的最新版本带来了GCC 4.9,它不能编译C++ 14.这似乎不是一个严重的问题,因为我可以在C++ 11中重写C++ 14结构.所以,我重写get_it()方法如下:

typename Container::Iterator get_it() const
{ 
  auto ret = typename Container::Iterator();
  return ret;
}

不幸的是它没有编译.两个编译器都会产生以下错误:

error: no type named ‘Iterator’ in ‘struct A’
   typename Container::Iterator get_it() const
                            ^

我也尝试过:

auto get_it() const -> decltype(typename Container::Iterator())
{ 
  auto ret = typename Container::Iterator();
  return ret;
}

但我得到完全相同的错误.

由于两个编译器无法识别返回类型,我认为无法确定它.但我真的不知道为什么.

有人可以解释一下为什么不编译并最终在C++ 11中编译重构的方法?



1> Columbo..:

你正在使用CRTP; LocateFunctions使用A(A)的不完全特化实例化,因此访问该特化的成员会给出相当误导性的错误消息("不...命名...在...中"而不是"......不完整").但是,在您的示例中,函数temploid get_it仅在(如果有)实例化之后A确实定义,使得typename-specifier格式良好.

至于解决方法,尝试实现类似的效果,例如通过

template 
typename T::Iterator get_it() const
{
    static_assert(std::is_same{}, "You ain't supposed to supply T!");
    auto ret = typename T::Iterator();
    return ret;
}

GCC 4.9演示.


Temploid?这是一个字吗?
@Quentin是的.它表示模板的非模板成员,受15年前开放的某个DR的影响.
推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有