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

时间:2018-09-26 09:53:21

标签: c++ sizeof sfinae c++03 decltype

在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的{​​{1}}版本。

  • 代码是否保证可以在C ++ 03中正常工作?

  • 是否可以得出结论,使用-std=c++03 -Wall -Wextrasfinaer将C ++ 11表达式SFINAE的任何用法都可以反向移植到C ++ 03?

1 个答案:

答案 0 :(得分:3)

表达式SFINAE有点灰。 C ++ 03对此基本上什么也没说。它既没有明确禁止它,也没有明确允许它。当代的实现不允许这样的构造,因为它造成了很大的实现复杂性,并且尚不清楚是否应允许这种构造,并且CWG at one point倾向于禁止它(请参阅2003年4月的注解),直到最终{{3} },部分是根据已添加到C ++ 11的decltypeconstexpr(请参阅N2634的简介)。

这一切都发生在CWG开始明确标记要追溯解决的问题的DR状态之前。

我认为这里最好的建议就是“询问您的编译器供应商”。在C ++ 11模式下支持表达式SFINAE的编译器不太可能会放弃在C ++ 03模式下的支持(供应商可能会将CWG 339视为缺陷报告并追溯应用,或将其视为扩展)。 OTOH,一个从来不支持C ++ 11的编译器,不太可能投资使SFINAE表达式正常工作所需的大量费用(实际上,直到最近,它才在某些主要的编译器 cough 中起作用)。我还怀疑一个仍然使用15年语言的地方不太可能使用这种支持所必需的现代工具链。