在开发一个应用程序,我有以下问题。我想返回一个空std::list<string>
当给定函数指针为空,或者功能,否则的结果。这是我的代码的简化版本:
typedef std::list<std::string> (*ParamGenerator)();
std::list<std::string> foo() {
/* ... */
ParamGenerator generator = ...;
if(generator)
return generator();
else
return {};
}
不过,我通常喜欢使用三元(?:
)运营商在这些情况下,所以我想用这种方式(像往常一样):
return generator ? generator() : {};
但得到这个错误:
somefile.cpp:143:46: error: expected primary-expression before ‘{’ token
somefile.cpp:143:46: error: expected ‘;’ before ‘{’ token
这是否意味着我不能使用三元运算返回使用其构造函数从initializer_list
创建的对象?是否有什么特别的原因?
标准中写道8.5.4.1:列表初始化
注:列表初始化,可以使用
- 如在变量定义的初始化(8.5)
- 如在新的表达式初始化(5.3.4)
- 在return语句(6.6.3)
- 作为函数参数(5.2.2)
- 作为下标(5.2.1)
- 作为参数传递给一个构造函数调用(8.5,5.2.3)
- 作为用于非静态数据成员初始化器(9.2)
- 在MEM-初始化(12.6.2)
- 在赋值的右手侧(5.17)
他们没有什么是一个三元运算符。更简约return 1?{}:{};
是无效的也是如此,你想要什么是不可能的。
当然,你可以显式调用构造函数std::list<std::string>{}
,但我会建议写出来的if
-else
块,你已经做了。
当你做{}
编译器有没有你期待的那种知识,所以它只是一个毫无意义的表达,编译器不知道该怎么做。在:
的双方分别进行评估,只有这样,编译器抱怨,如果该类型不匹配。我只是这样做:
return generator ? generator() : std::list<std::string>();
如果你真的很喜欢三元运算符,你可以尝试这样的事:
return generator ? generator() : decltype(generator()) { "default value", "generator was empry" };
如果以后改变返回类型,将工作均匀。
另一种可能性是定义一个包装函数的条件运算符:
template<class T> T& conditional(bool b, T&x, T&y) { return b ? x : y; }
template<class T> const T& conditional(bool b, const T&x, const T&y) { return b ? x : y; }
这允许您拨打:
return conditional(generator, generator(), {});