【问题标题】:How does providing a class a template solve invalid constexpr dependencies? C++为类提供模板如何解决无效的 constexpr 依赖? C++
【发布时间】:2019-05-07 03:08:47
【问题描述】:

类似乎在另一个 constexpr 上下文中调用其 constexpr 成员函数时遇到问题。例如在我提出的这段代码in an earlier question 中可以看到这种行为:

struct Foo {
    constexpr static bool TRUE() {
        return true;
    }
    static_assert(Foo::TRUE(), ""); //ERROR
};

由于static_assert 依赖于Foo::TRUE() 编译失败,因为Foo::TRUE() 在此上下文中尚未完全解析。


那么向Foo 添加单个模板如何解决整个问题呢?:

template<int x>
struct Foo {
    constexpr static bool TRUE() {
        return true;
    }
    static_assert(Foo::TRUE(), ""); //compiles fine
};

在所有这些见解之后,这里的代码不应该编译 - 但它可以编译。这似乎没有意义,因为与非模板版本没有任何区别。

另外,TRUE()-functions 和 static_assert-calls 应该总是和 Foo&lt;&gt; 类一样多,所以编译时应该会出现同样的依赖问题。


我正在使用 Visual Studio 17 社区版本 15.9.0 - 感谢您的帮助!

【问题讨论】:

    标签: c++ visual-studio templates c++17 constexpr


    【解决方案1】:

    这是CWG 1626

    标准应该明确指出,constexpr 成员函数在其类完成之前不能在常量表达式中使用。例如:

    template<typename T> struct C {
      template<typename T2> static constexpr bool _S_chk() {
        return false;
      }
      static const bool __value = _S_chk<int>();
    }; 
    
    C<double> c;
    

    当前的实现接受这一点,尽管它们拒绝相应的非模板案例:

    struct C {
      static constexpr bool _S_chk() { return false; }
      static const bool __value = _S_chk();
    };
    
    C c; 
    

    大概模板情况应该和非模板情况处理一致。

    【讨论】:

    • 所以根据标准,模板化的Foo 也不应该工作,但实现允许吗?我明白了
    • 什么?该提案来自 2013 年,与当前标准相比相当陈旧。尤其是对于 C++17 中的if constexpr,这种限制会给元编程带来很大的痛苦。我的意思是,使用静态分支计算类型的最简单方法是编写一个带有auto 返回的函数,然后在函数体中分支。如果这个提案最终集成到标准中,那么这个静态函数必须移到模板之外......
    • @liliscent 这不是一个提案,这是一个开放的核心语言问题。
    • @Barry 是的,我的意思是这个问题。只是问题中有一个建议,禁止在模板中使用这种类型。会带来很多不便。
    • @liliscent:实际上不会有太大变化。 if constexpr 表示您在函数内部。并且函数定义被认为是在类完成后才出现,所以你应该可以调用constexpr成员就好了。
    猜你喜欢
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    • 2014-09-05
    • 2016-03-21
    • 2012-11-16
    • 2022-01-17
    • 2022-11-01
    相关资源
    最近更新 更多