自动无法推断正确的返回类型

时间:2019-05-09 12:07:33

标签: c++ c++14

我已声明一个函数,该函数返回auto类型的参数化模板类的shared_ptr。就我而言,如果我添加“ else”条件,编译器会抱怨类型不完整。使用相同的功能签名,可以在一种情况下正常工作。任何使编译器满意的优雅解决方案。

auto getCustomerDataSource(ptree const &node){
   const auto dataSource = node.get<std::string>("<xmlattr>.Type");
   const auto sourceString = node.get<std::string>("SourceString");
   if (dataSource == "File") {
     return std::make_shared<CustomerData<CFileSource>>(sourceString);
   } else if (dataSource == "DataBase") {
     return std::make_shared<CustomerData<CDatabaseSource>>(sourceString);
   }
 }

3 个答案:

答案 0 :(得分:14)

您的代码违反了C ++标准[dcl.spec.auto.8]中的以下规则:

  

如果声明的返回类型包含占位符类型的函数具有多个未丢弃的return语句,则会为每个此类return语句推导返回类型。 如果推导的类型在每次推导中都不相同,则说明程序格式错误


  

CFileSourceCDatabaseSource是两种可能的算法,用户可以选择一种算法来构建CustomerData对象。

一个问题是,您试图对运行时确定的内容使用静态多态性(模板)。因此,更好的解决方案是为您的算法提供具有共同基础的多态类。然后,您可以指向base作为CustomerData的成员变量的指针,而该变量不再是模板。

答案 1 :(得分:7)

使用auto时,对于程序可能采用的每种可能的路径,推导的函数必须的返回类型必须相同。在这里,您的函数有3种可能的返回类型:

  1. 第一个if正文被执行:std::shared_ptr<CustomerData<CFileSource>>
  2. 第二个if正文被执行:std::shared_ptr<CustomerData<CDatabaseSoruce>>
  3. 均未执行:void

这无效。

答案 2 :(得分:4)

  

CFileSource和CDatabaseSource是用户可能使用的两种算法   可以选择一个来构建CustomerData对象。你可以考虑   getCustomerDataSource作为工厂方法,它返回以下对象的shared_ptr   CustomerData <>基于传递的参数。

您似乎有以下误解:同一模板的两个实例之间没有任何关系,只是它们是同一模板的实例。

考虑:

NULL

您无法代替newtable的类型,因为template<typename T> struct Foo{}; ??? bar(bool x) { if (x) return Foo<int>(); return Foo<double>(); } ???毫无关联。它们是相同的tempalte的实例,但仅此而已。

也许您想要这样的东西:

Foo<int>

因为现在Foo<double>struct Moo_base {}; template <typename T> struct Moo : Foo_base {}; 都可以通过Moo<int>来传递。