2014-02-17 79 views
4

以下代碼被clang接受並被gcc拒絕。我想知道這是否是一個錯誤或我失去了一些東西:靜態成員函數不被接受爲constexpr參數

#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

由於函數調用替換的規則,我認爲clang在這裏是正確的。 – Simple

+0

我這麼認爲,如果我們改變Ar類型爲'int','Apply (1,foo)'按預期工作。 – Jarod42

+0

@ Jarod42:是的,我注意到,雖然試圖減少這個問題。對不起,我忘了提及它。 – hivert

回答

2

我在gcc(4.8.1)的bug已經降低到以下幾點:

#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; 
} 
+0

謝謝!我會向GCC報告。 – hivert

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); 

id定義更改通過intAr使問題消失。所以這顯然是一個錯誤!