这是在C++ 03中执行"Expression SFINAE"的有效方法吗?

Vit*_*meo 8 c++ sizeof decltype sfinae c++03

在C++ 11中,SFINAE很容易判断表达式是否有效.举个例子,假设检查某些东西是否可流动:

template <typename T>
auto print_if_possible(std::ostream& os, const T& x) 
    -> decltype(os << x, void());
Run Code Online (Sandbox Code Playgroud)

print_if_possible将只参加重载解析如果os << x是合式表达.

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);
Run Code Online (Sandbox Code Playgroud)

godbolt.org上的实例


似乎g ++clang ++的最新版本都接受了这个sizeof版本-std=c++03 -Wall -Wextra.

  • 代码是否保证在C++ 03中按预期工作?

  • 它是正确的结论是C++ 11的表达SFINAE的任何使用可回迁C++ 03使用到sfinaersizeof

T.C*_*.C. 2

SFINAE的表情有点灰暗。C++03 基本上没有提及这个主题。它既没有明确禁止,也没有明确允许。当代的实现不允许此类构造,因为它导致了相当大的实现复杂性,并且尚不清楚它是否应该被允许,并且 CWG一度倾向于禁止它(参见 2003 年 4 月的注释),但最终改变了方向,部分原因是的decltypeconstexpr添加到 C++11 中(参见 N2634 的介绍)。

这一切都发生在 CWG 开始明确标记其决议应追溯适用的问题的 DR 状态之前。

我认为这里最好的建议就是“询问你的编译器供应商”。在 C++11 模式下支持表达式 SFINAE 的编译器不太可能在 C++03 模式下取消该支持(供应商可能将 CWG 339 视为缺陷报告并追溯应用它,或将其视为扩展)。OTOH,一个从未支持 C++11 的编译器不太可能投入表达式 SFINAE 工作所需的大量成本(事实上,直到最近它才在某个主要编译器中工作)我还怀疑,一个仍然使用 15 年历史语言的地方不太可能使用此类支持所需的现代工具链。