32

在开发应用程序时,我遇到了以下问题。当给定的函数指针为空时,我想返回一个空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?有什么特别的原因吗?

4

4 回答 4

25

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)
  • 在 mem-initializer (12.6.2) 中
  • 在作业的右侧(5.17)

它们都不是三元运算符。越简约return 1?{}:{};也是无效的,你想要的都是不可能的。

当然,您可以显式调用构造函数std::list<std::string>{},但我建议您像以前那样写出if--block else

于 2012-04-02T19:56:24.780 回答
9

当您这样做时{},编译器不知道您期望的类型,因此它只是一个无意义的表达式,编译器不知道如何处理。的双方:都是单独评估的,只有这样,如果类型不匹配,编译器才会抱怨。我会这样做:

return generator ? generator() : std::list<std::string>();
于 2012-04-02T19:48:06.437 回答
2

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

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

即使您稍后更改返回类型,它也会起作用。

于 2012-04-02T20:36:33.173 回答
2

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

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(), {});
于 2019-02-09T00:08:51.420 回答