【问题标题】:decltype(fun()) for consteval methodsdecltype(fun()) 用于 consteval 方法
【发布时间】:2021-02-22 00:00:26
【问题描述】:

考虑以下代码。我可以用 GCC 10.2.0 和 Clang 11.0.0 编译它(如预期的那样):

#include <iostream>

template<int> 
struct T {
  static constexpr auto fun() noexcept { return 0; }
  using type = std::remove_cvref_t<decltype(fun())>; 
};

int main() {
    decltype(T<1>::fun()) a = 1;
    std::cout << a; 
}

如果我将 constexpr 替换为 consteval,那么 Clang 会抱怨 std::remove_cvref_t&lt;decltype(fun())&gt;

错误:不能在立即调用之外获取 consteval 函数 'fun' 的地址

GCC 编译它就好了。为什么?

【问题讨论】:

  • 这是一个clang bug。请参阅链接的proposal,它与您的代码具有基本相同的示例。

标签: c++ c++20 consteval


【解决方案1】:

正如在 cmets 中所说的那样,这是 CLang 错误。

仅当函数是静态方法时才会出现此错误,如果它是全局函数,则代码可以工作(请参阅工作 online example here)。

因此解决此问题的一种方法是使用全局函数来转发静态方法的结果。我在下面做了一个更高级的全局转发示例。

Try it online!

#include <iostream>
#include <type_traits>

template <typename T, typename ... Args>
static consteval auto forward_fun(Args ... args) {
    return T::fun(args...);
}

template <int I> 
struct T {
    static consteval auto fun(int i, bool f) noexcept {
        return i + 1;
    }
    using type = std::remove_cvref_t<decltype(forward_fun<T>(123, true))>;
};

int main() {
    T<1>::type a = 1;
    std::cout << a; 
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多