问题描述
请考虑以下代码。我可以使用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<decltype(fun())>
:
GCC编译就可以了。为什么?
解决方法
正如在问题评论中已经说过的,这是CLang错误。
仅当函数是静态方法时才出现此错误,如果它是全局函数则代码可以工作(请参见工作online example here)。
因此,解决此问题的一种方法是使用全局函数转发静态方法的结果。我在下面做了一个更高级的此类全局转发示例。
#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;
}