【问题标题】:Auto return type in template模板中的自动返回类型
【发布时间】:2017-05-16 09:50:24
【问题描述】:

我的代码中的各个模块中有多个数据类,我不打算对其进行任何修改。 我为它们每个都有一个容器类,它有一个指向这个数据类的指针,还有一个指向一个类的指针,该类旨在在不知道它们的情况下保存这些类。

所以在我实现的容器类中:

DataClass GetMyData (void){
   return myData;
}

在我创建的这些硬币容器类的集合中

template<class ContainerClass>
ContainerClass  GetContainer (void);

template<class ContainerClass>
auto    GetData (void){
    GetContainer<ContainerClass> ().GetMyData();
}

但是每当我尝试使用这个 GetData 函数时,我都会得到错误

返回'auto'的函数在定义之前不能使用

所以我的问题是,在这种情况下是否可以使用 auto (c++11),或者我必须使用 2 个类制作我的模板?

【问题讨论】:

  • 在 C++11 中,这根本不可能:返回类型推导仅适用于那里的 lambdas。是 C++14 也为函数添加了它。
  • 谢谢 Angew,我想我也必须使用另一个模板参数...
  • @MartinZink - 你没有
  • OP:@Angew 的意思是返回类型推导是 C++14 的一个特性,所以它永远不会使用严格的 C++11 标准编译器进行编译

标签: c++ c++11 templates auto


【解决方案1】:

如果您在GetData() 中忘记了return,则auto 无法工作 无法返回与模板类型的getData() 返回的相同类型(感谢 Jarod42!) .

无论如何...给定几个结构如下

struct A
 { int getData () const { return 1; } };

struct B
 { std::string getData () const { return "abc"; } };

在 C++14 中 GetData() 可以简单地写成

template <class CC>
auto GetData ()
 { return CC{}.getData(); }

但这在 C++11 中不起作用;在 C++11 中你可以写

template <class CC>
auto GetData () -> decltype( CC{}.getData() )
 { return CC{}.getData(); }

在 C++11 之前没有(这种用法)auto

--- 编辑---

正如 StoryTeller 所指出的,decltype( CC{}.getData() ) 的使用假定 CC 类型是默认可构造的。

在我编写的玩具示例中,这不是问题,因为我在函数体中使用了CC{}

在简单的情况下,您可以在decltype() 表达式中反映函数体中返回的内容;例如,如果你传递一个CC 类型的对象,你可以这样写

template <class CC>
auto GetData (CC const & cc) -> decltype( cc.getData() )
 { return cc.getData(); }

但并非如此简单:在某些情况下,您知道返回的值是给定的表达式,但函数很复杂,无法在 decltype() 表达式中反映它。

所以,为了避免可构造/不可构造的问题,最好使用(正如 StoryTeller 所建议的那样;谢谢)std::declval;如下,举例说明

template <class CC>
auto GetData () -> decltype( std::declval<CC>().getData() )
 { /* something complicated ... */ return something.getData(); }

【讨论】:

  • 没有返回,auto 应该是void
  • @Jarod42 - 你是对的;修改了我的答案以纠正这一点;谢谢。
  • 一般情况下最好使用std::declval。为什么类必须是默认可构造的?
  • @StoryTeller - 嗯……在decltype()是的;但是你可以在函数体中使用std::declval
  • @max66 - 在您的示例中,您在适当的位置构造对象,因此您有一个要求。 OP 的代码不需要使用默认构造函数来构造任何东西,因此应该建议他们使用declval。 (虽然OP也可以直接使用自己的GetContainer函数)。
猜你喜欢
  • 2020-05-02
  • 1970-01-01
  • 2016-10-29
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多