三元运算+ C ++ 11从initializer_list构造

问题描述 投票:24回答:4

在开发一个应用程序,我有以下问题。我想返回一个空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创建的对象?是否有什么特别的原因?

c++ constructor c++11 ternary-operator initializer-list
4个回答
18
投票

标准中写道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块,你已经做了。


7
投票

当你做{}编译器有没有你期待的那种知识,所以它只是一个毫无意义的表达,编译器不知道该怎么做。在:的双方分别进行评估,只有这样,编译器抱怨,如果该类型不匹配。我只是这样做:

return generator ? generator() : std::list<std::string>();

2
投票

如果你真的很喜欢三元运算符,你可以尝试这样的事:

return generator ? generator() : decltype(generator()) { "default value", "generator was empry" };

如果以后改变返回类型,将工作均匀。


0
投票

另一种可能性是定义一个包装函数的条件运算符:

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(), {});
© www.soinside.com 2019 - 2024. All rights reserved.