在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版本。
  • 代码是否保证能按C++ 03的预期运行?
  • 是否可以得出结论,使用sfinaersizeof将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年语言的地方不太可能使用这种支持所必需的现代工具链。

    09-30 14:03
    查看更多