我正在尝试创建一个函数,其返回类型应取决于switch语句,例如:
auto function_name (int value) {
switch (value) {
case 1 : {return 2.3;}
case 2 : {return 1;}
case 3 : {return "string";}
}
}
但是我不能因为一个错误:
error: inconsistent deduction for auto return type: 'double' and then 'int'
如何通过功能来创建与上面的示例类似的内容?
答案 0 :(得分:13)
C ++中的函数只能具有返回的单个类型。如果将auto
用作返回类型,并且具有不同的返回语句以返回不同的类型,则该代码格式不正确,因为它违反了单一类型规则。
需要使用std::variant
或std::any
的地方。如果您有一些可以通过某个运行时值返回的不同类型,则可以将这些类型之一用作“通用类型”。 std::variant
的限制更大,因为您必须指定可能的类型,但是它比std::any
便宜,因为您知道它可能是什么类型。
std::variant<double, int, std::string> function_name (int value) {
using namespace std::literals::string_literals;
switch (value) {
case 1 : {return 2.3;}
case 2 : {return 1;}
case 3 : {return "string"s;} // use ""s here to force it to be a std::string
}
}
将让您返回不同的类型。
答案 1 :(得分:6)
如果在编译时知道函数参数,则可以使用编译时分配,例如
template <int N>
constexpr auto function_name()
{
if constexpr(N == 1)
return 2.3;
else if constexpr (N == 2)
return 1;
else
return "string";
}
可以如下实例化和调用
std::cout << function_name<1>() << "\n";
对于if constexpr
部分, C ++ 17是必需的。请注意,在将返回值绑定到变量时,请仔细选择类型(例如,不要将double
隐式转换为int
),使用类型推导或variant
-类型如现有答案所示。
请注意,正如@NathanOliver在评论中指出的那样,还有一个C ++ 17之前的解决方案,它使用模板特殊化而不是if constexpr
:
template <int N> constexpr auto function_name() { return "string"; }
template <> constexpr auto function_name<1>() { return 2.3; }
template <> constexpr auto function_name<2>() { return 1; }
此模板的使用及其专业化与上面的内容没有什么不同。
答案 2 :(得分:2)
错误消息说明了一切:函数的所有分支必须返回相同的类型。此限制并不特定于auto
返回类型。
一个可能的解决方法:
std::variant<double, int, std::string> function_name(int value) {
switch(value) {
case 1 : return 2.3;
case 2 : return 1;
case 3 : return "string";
default: throw;
}
}
或者,您可以使用boost::variant
。