"如果constexpr"与"尝试constexpr功能"警告相互作用

Quu*_*one 7 c++ template-meta-programming c++17 if-constexpr

我声称这个程序应该是格式良好的:它声明了一个constexpr成员函数S<int>.但是,GCC和Clang都拒绝接受这个计划.

template<class T>
struct S {
    constexpr int foo() {
        if constexpr (std::is_same_v<T, int>) {
            return 0;
        } else {
            try {} catch (...) {}
            return 1;
        }
    }
};

int main()
{
    S<int> s;
    return s.foo();  // expect "return 0"
}
Run Code Online (Sandbox Code Playgroud)

GCC说:

错误:'constexpr'功能'尝试'

Clang说:

错误:constexpr函数中不允许使用语句

他们似乎都没有注意到"try"语句位于语句的废弃分支中if constexpr.

如果我将try/ catchout分解为非constexpr成员函数void trycatch(),那么Clang和GCC都会再次对代码感到满意,即使它的行为应该等同于不满意的版本.

template<class T>
struct S {
    void trycatch() {
        try {} catch (...) {}
    }
    constexpr int foo() {
        if constexpr (std::is_same_v<T, int>) {
            return 0;
        } else {
            trycatch();  // This is fine.
            return 1;
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

这是

  • 海湾合作委员会和克朗的一个错误?
  • GCC和Clang忠实执行标准中的缺陷?
  • 实施问题的因质量"条件constexprness"foo()

(不相关的背景:我正在any::emplace<T>()为一个分配器感知版本实现constexpr ,any其分配器可能是constexpr-per- P0639(即它可能缺少deallocate成员函数)或者可能没有.在前一种情况下,我们不想要或不需要try;在后一种情况下,我们需要try在调用deallocate构造函数时调用T.)

asc*_*ler 11

编制者遵守标准.C++ 17草案N4659说([dcl.constexpr] /(3.4.4)):

constexpr函数的定义应满足以下要求:

  • ...

  • 它的函数体应该是= delete,= default或者是不包含的复合语句

    • ...

    • 一个试块,或

    • ...

并且没有任何"废弃语句"的规则,例如else你的S<int>::foo覆盖此规则中的语句.关于废弃语句指定的唯一特殊事项是废弃语句未实例化,废弃语句中的odr使用不会导致需要使用声明的定义,并且return在确定函数的真实返回类型时忽略废弃语句占位符返回类型.

我没有看到任何现有的C++问题讨论这个问题,提出的论文P0292R1 if constexpr没有涉及与constexpr函数的交互.