以下代码被clang接受并被gcc拒绝。我想知道这是一个错误还是我错过了一些东西:
#include <array>
template<typename T>
static constexpr T Apply(T in, T fun(T)) {
return fun(in);
}
template <typename T, size_t N> struct Triangle {
using Ar = std::array<T, N>;
static constexpr Ar foo(Ar line) { return line; }
static constexpr Ar results = Apply<Ar>( {{ 1 }}, foo ); // foo({1}); is ok
};
template <typename T, size_t N> constexpr std::array<T, N> Triangle<T, N>::results;
int main() {
Triangle<unsigned long, 10>::results[0];
}
GCC错误消息是:
binom2.cpp: In instantiation of ‘constexpr const std::array<long unsigned int, 10ul> Triangle<long unsigned int, 10ul>::results’:
binom2.cpp:16:32: required from here
binom2.cpp:11:57: in constexpr expansion of ‘Apply<std::array<long unsigned int, 10ul> >(std::array<long unsigned int, 10ul>{std::__array_traits<long unsigned int, 10ul>::_Type{1ul}}, Triangle<T, N>::foo<long unsigned int, 10ul>)’
binom2.cpp:5:16: error: expression ‘Triangle<T, N>::foo<long unsigned int, 10ul>’ does not designate a constexpr function
return fun(in);
^
答案 0 :(得分:2)
我已将gcc(4.8.1)错误减少到以下内容:
#include <array>
using Ar = std::array<unsigned long, 10>;
template<typename T>
constexpr T Apply(const T& in, T (*f)(const T&)) { return f(in); }
#if 1 // if disable, bug occurs
// error: expression 'id' does not designate a constexpr function
template<>
constexpr Ar Apply<Ar>(const Ar& in, Ar (*f)(const Ar&)) { return f(in); }
#endif
constexpr Ar ApplyAr(const Ar& in, Ar (*f)(const Ar&)) { return f(in); }
static constexpr Ar id(const Ar& line) { return line; }
static constexpr Ar ar1 = {{1}};
static constexpr Ar results1 = Apply<Ar>(ar1, &id); // Fail when #if 0
static constexpr Ar results2 = ApplyAr(ar1, &id);
static constexpr Ar results3 = id(ar1);
int main() {
return 0;
}
答案 1 :(得分:1)
这绝对是个错误。这是最简化的版本,我设法来了:
constexpr int Apply(int f(const int)) { return f(0); }
using Ar = int;
constexpr int id(const Ar i) { return i; }
constexpr int results1 = Apply(id);
在Ar
的定义中将int
更改为id
会使问题消失。所以这显然是一个错误!