【发布时间】:2014-01-11 10:18:11
【问题描述】:
我似乎记得从一些可靠的消息来源(即委员会成员在非官方渠道中发言)那里听到模糊的 cmets,即 C 类型泛型表达式不会添加到 C++ 中,因为它们不能。
据我所知,与 C++ 模板和重载相比,类型泛型表达式非常有限,但没有可能需要将交互定义为特殊情况。
类型泛型表达式由控制表达式以及类型和子表达式之间的一系列“关联”组成。根据控制表达式的静态类型和为子表达式列出的类型来选择子表达式,并用它代替 TGE。匹配是基于 C 的类型兼容性概念,据我所知,这相当于 C++ 在单一定义规则 (ODR) 下具有 extern 链接的类型标识。
如果派生类控制表达式在 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';
}
【问题讨论】:
-
也许负责解决泛型的事情必须先于弄清楚类如何工作的事情。因此,您将无法泛化类,因此您将拥有仅适用于某些类型的功能。
-
@leewangzhong 嗯,它的工作方式与 C 中的相同。它适用于所有类型,只是不能深入了解继承。
-
我的意思是,在解析泛型时可能无法识别 C++ 类型。
-
@leewangzhong:C++ 必须指定
_Generic的工作方式,C++ 肯定会指定它在识别 C++ 类型后解决。 (无论如何,这还很早,因为解析需要它。有关更多详细信息,请参阅“最令人烦恼的解析”。) -
你能告诉我们不可能的消息来源吗?上下文可能会有所帮助。