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

auto fail to deduce correct return type

本文关键字:返回类型 推断出      更新时间:2023-10-16

我已经声明了一个函数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);
}
}

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

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


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

问题是您正在尝试将静态多态性(模板)用于在运行时决定的内容。因此,更好的解决方案是将您的算法作为具有公共基础的多态类提供。然后,你可以做一个指向 base 的指针,作为CustomerData的成员变量,它不再需要是模板。

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

  1. 执行第一个if主体:std::shared_ptr<CustomerData<CFileSource>>
  2. 执行第二个if体:std::shared_ptr<CustomerData<CDatabaseSoruce>>
  3. 两者都不执行:void

这是无效的。

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

看来您的误解如下:同一模板的两个实例化之间除了它们是同一模板的实例化之外,没有任何关系。

考虑:

template<typename T>
struct Foo{};
??? bar(bool x) {
if (x) return Foo<int>();
return Foo<double>();
}

没有一种类型可以代替???因为Foo<int>Foo<double>没有任何关系。它们是同一时间的实例,但仅此而已。

也许你想要这样的东西:

struct Moo_base {};
template <typename T>
struct Moo : Foo_base {};

因为现在Moo<int>Moo<double>都可以通过std::shared_ptr<Moo_base>传递。