【发布时间】:2014-03-16 20:14:21
【问题描述】:
以下代码被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);
^
【问题讨论】:
-
我认为clang在这里是正确的,因为函数调用替换的规则。
-
我想是的,如果我们将 Ar 类型更改为
int,Apply<Ar>(1, foo)将按预期工作。 -
@Jarod42 :是的,我在尝试减少问题时注意到了这一点。对不起,我忘了提。
-
借助
Apply<Ar>的专业化(与Apply<T>做同样的事情),它可以工作...... gcc 的 SO 错误(我的部分是 4.8.1)。 -
@Jarod42:对不起!我不明白你的意思。你能写(可能在一个答案中,我会接受它)有效的变化,这是一个错误的证据吗?
标签: c++ templates gcc c++11 constexpr