来自 initializer_list 的三元运算符 + C++11 构造函数
Posted
技术标签:
【中文标题】来自 initializer_list 的三元运算符 + C++11 构造函数【英文标题】:Ternary operator + C++11 constructor from initializer_list 【发布时间】:2012-04-16 11:34:41 【问题描述】:在开发应用程序时,我遇到了以下问题。当给定的函数指针为空时,我想返回一个空的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
返回使用其构造函数创建的对象?有什么特别的原因吗?
【问题讨论】:
我的建议是:根本不要这样做。让它成为一个通用算法,它接受一个迭代器(其类型是一个模板参数),所以当你意识到std::list
是一个糟糕的选择时,你可以相对轻松地改用其他东西。
@JerryCoffin 我可能会接受这个建议;)。我想知道它是否有可能(或者为什么它不能做到)。
好的,很公平。这是一个有趣的问题(我对此投了赞成票),尽管我认为确切的应用程序可能不是最好的。
其实,现在想想,我不能模板化这个函数。该函数实际上是从共享对象导出的,所以我需要在编译期间知道返回类型。我同意在不同的情况下,模板化的解决方案会更好。
【参考方案1】:
8.5.4.1 中的标准写入:列表初始化
注意:可以使用列表初始化
作为变量定义中的初始化器 (8.5) 作为新表达式 (5.3.4) 中的初始化程序 在返回语句中 (6.6.3) 作为函数参数 (5.2.2) 作为下标 (5.2.1) 作为构造函数调用的参数(8.5、5.2.3) 作为非静态数据成员的初始化器 (9.2) 在内存初始化器 (12.6.2) 中 在作业的右侧 (5.17)
它们都不是三元运算符。更简约的return 1?:;
也是无效的,你想要的都是不可能的。
当然,您可以显式调用构造函数std::list<std::string>
,但我建议您像之前那样写出if
-else
-block。
【讨论】:
太好了,这就是我正在寻找的理由。【参考方案2】:当您执行 时,编译器不知道您期望的类型,因此它只是一个无意义的表达式,编译器不知道如何处理。
:
的两边都是单独评估的,只有这样,如果类型不匹配,编译器才会抱怨。我会这样做:
return generator ? generator() : std::list<std::string>();
【讨论】:
【参考方案3】:如果你真的喜欢三元运算符,你可以试试这样:
return generator ? generator() : decltype(generator()) "default value", "generator was empry" ;
即使您稍后更改返回类型,它也会起作用。
【讨论】:
【参考方案4】:另一种可能性是为条件运算符定义一个包装函数:
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(), );
【讨论】:
以上是关于来自 initializer_list 的三元运算符 + C++11 构造函数的主要内容,如果未能解决你的问题,请参考以下文章