我已声明一个函数,该函数返回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);
}
}
答案 0 :(得分:14)
您的代码违反了C ++标准[dcl.spec.auto.8]中的以下规则:
如果声明的返回类型包含占位符类型的函数具有多个未丢弃的
return
语句,则会为每个此类return
语句推导返回类型。 如果推导的类型在每次推导中都不相同,则说明程序格式错误。
CFileSource
和CDatabaseSource
是两种可能的算法,用户可以选择一种算法来构建CustomerData
对象。
一个问题是,您试图对运行时确定的内容使用静态多态性(模板)。因此,更好的解决方案是为您的算法提供具有共同基础的多态类。然后,您可以指向base作为CustomerData
的成员变量的指针,而该变量不再是模板。
答案 1 :(得分:7)
使用auto
时,对于程序可能采用的每种可能的路径,推导的函数必须的返回类型必须相同。在这里,您的函数有3种可能的返回类型:
if
正文被执行:std::shared_ptr<CustomerData<CFileSource>>
if
正文被执行:std::shared_ptr<CustomerData<CDatabaseSoruce>>
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>
来传递。