在C++ 11中,很容易用SFINAE判断表达式是否有效。举个例子,想象一下检查是否有流媒体:
template <typename T>
auto print_if_possible(std::ostream& os, const T& x)
-> decltype(os << x, void());
如果
print_if_possible
是格式正确的表达式,则os << x
将仅参与重载解析。live example on godbolt.org
我需要在C++ 03中执行相同的操作,并且我发现
sizeof
可以提供帮助(因为我需要一个表达式的未评估上下文)。这是我想出的:template <int> struct sfinaer { };
template <typename T>
void print_if_possible(std::ostream& os, const T& x,
sfinaer<sizeof(os << x)>* = NULL);
live example on godbolt.org
似乎最新版本的g++和clang++都接受带有
sizeof
的-std=c++03 -Wall -Wextra
版本。sfinaer
和sizeof
将C++ 11表达式SFINAE的任何用法都可以反向移植到C++ 03? 最佳答案
表达式SFINAE有点灰。 C++ 03对此基本上什么也没说。它既没有明确禁止它,也没有明确允许它。当代的实现不允许这种构造,因为它导致实现的实质复杂性,并且尚不清楚是否应允许这种构造,并且CWG在最终at one point之前倾向于reversed course倾向于禁止它(请参阅2003年4月的说明),部分原因是decltype
和已添加到C++ 11的constexpr
(请参阅N2634的简介)。
在CWG开始明确标记要追溯解决的问题的DR状态之前,这一切都发生了。
我认为这里最好的建议就是“询问您的编译器供应商”。在C++ 11模式下支持表达式SFINAE的编译器不太可能会放弃在C++ 03模式下的支持(供应商可能会将CWG 339视为缺陷报告并追溯应用,或将其视为扩展)。 OTOH,一个从来不支持C++ 11的编译器,不太可能投资表达SFINAE起作用所需的大量成本(实际上,直到最近,它才在某些主要的编译器咳嗽中起作用)。我还怀疑一个仍然使用15年语言的地方不太可能使用这种支持所必需的现代工具链。