为什么C类通用表达式不能与C ++兼容?

时间:2013-12-23 08:10:49

标签: c++ c c11

我似乎记得听到几个可靠来源(即委员会成员在非官方渠道中发言)的模糊评论,C类通用表达式不会被添加到C ++,因为它们不能。

据我所知,与C ++模板和重载相比,类型泛型表达式非常有限,但是没有可能需要定义为特殊情况的交互。

类型通用表达式由控制表达式和类型与子表达式之间的一系列“关联”组成。基于控制表达式的静态类型和子表达式列出的类型选择子表达式,并替换它代替TGE。匹配基于类型兼容性的C概念,据我所知,它等同于单定义规则(ODR)下具有extern链接的类型的C ++标识。

如果派生类控制表达式在C ++中选择基类关联会很好,但由于C没有继承,因此交叉兼容性不需要这样的精确性。这被认为是一个绊脚石吗?

编辑:至于更具体的细节,C11已经提供了保留所选子表达式的值类别(左值),并且似乎要求TGE是一个常量表达式(无论如何) category)只要它的所有操作数都是,包括控制表达式。这可能是C语言缺陷。在任何情况下,C ++ 14根据可能被评估的内容定义常量表达式,并且TGE规范已经说过未选择的子表达式未被评估。

重点是TGE操作原理看起来很简单,可以移植而不会在以后造成麻烦。

至于为什么 C ++ TGE会有用,除了最大化C和C ++的交集之外,它们可以用来实现static_if,没有极具争议的条件声明功能。我不是static_if的支持者,但“有那个。”

template< typename t >
void f( t q ) {
    auto is_big = _Generic( std::integral_constant< bool, sizeof q >= 4 >(),
        std::true_type: std::string( "whatta whopper" ),
        std::false_type: "no big deal"
    );
    auto message = _Generic( t, double: "double", int: 42, default: t );
    std::cout << message << " " << is_big << '\n';
}

1 个答案:

答案 0 :(得分:2)

“不能”也许太强大了。 “不确定是否可能”更有可能。

如果要将此功能添加到C ++中,则应完全指定它,包括与现有C ++功能的所有交互,其中许多功能在设计时并未考虑_Generic。例如。 C中不存在typeid,但应该在C ++中工作。您可以将_Generic表达式用作constexpr吗?作为模板参数?它是lvalue吗?你可以获取它的地址并将其分配给函数指针,并获得重载解析吗?你能做模板参数演绎吗?你能和auto一起使用吗?等

另一个复杂因素是_Generic的主要用例是宏的,它与C ++命名空间不相称。来自acos的{​​{1}}示例就是一个明显的例子。 C ++已经禁止了C的标准宏,并要求它们是函数,但这不适用于tgmath