【问题标题】:Is this a valid way of performing "Expression SFINAE" in C++03?这是在 C++03 中执行“表达式 SFINAE”的有效方法吗?
【发布时间】:2018-09-26 09:53:20
【问题描述】:

在 C++11 中,很容易对表达式是否有效进行 SFINAE。举个例子,想象一下检查某些东西是否可以流式传输:

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

print_if_possible 只会在os &lt;&lt; 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++ 的最新版本都接受带有-std=c++03 -Wall -Wextrasizeof 版本。

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

  • 是否可以断定 C++11 表达式 SFINAE 的任何用法都可以使用 sfinaersizeof 向后移植到 C++03?

【问题讨论】:

  • 你为什么把, 0放在sizeof里面?在这个特定的例子中你需要它吗?
  • @Evg:不需要,已删除。
  • sfinaer 是个好名字。
  • 考虑您的问题...如果表达式是位域,您将需要 , 0 in sizeof
  • 如果&lt;expression&gt;.operator,(0) 无效,可能会有一点副作用。

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


【解决方案1】:

表达式 SFINAE 有点灰。 C++03 基本上没有在这个问题上说什么。它既没有明确禁止它,也没有明确允许它。当代的实现不允许这样的结构,因为它导致了相当大的实现复杂性,并且不清楚它是否应该被允许,并且 CWG 倾向于禁止它(参见 2003 年 4 月的注释),然后最终 reversed course,部分在decltypeconstexpr 添加到 C++11 的光(参见 N2634 的介绍)。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多