2016-07-15 38 views
0

我可以寫一個constexpr函數執行類型推演但不使用傳遞給它的對象:方便constexpr功能

template <int N> 
struct Foo 
{ 
    static const int value = N; 
}; 

template <typename T> 
constexpr int get_value(T const &) 
{ 
    return T::value; 
} 

void huey() 
{ 
    Foo<3> three; 
    static_assert(get_value(three) == 3, ":("); 
} 

但是,如果參數get_value一些其他操作的結果,這方法失敗:

template <int N> 
Foo<N + 1> increase(Foo<N> const &) 
{ 
    return {}; 
} 

void dewey() 
{ 
    Foo<6> six; 
    static_assert(get_value(increase(six)) == 7, ":("); 
} 

編譯器(正確)抱怨increase(six)不是一個常量表達式。我可以這樣解決這個問題:

template <typename T> 
constexpr int get_value2() 
{ 
    return T::value; 
} 

void louie() 
{ 
    Foo<4> four; 
    static_assert(get_value2<decltype(increase(four))>() == 5, ":("); 
} 

,但我不喜歡多餘的decltype -gymnastics。我可以引入一個宏:

#define GET_VALUE(x) get_value2<decltype(x)>() 

但我想避免宏,如果可能的話。有沒有任何方法可以讓沒有宏的方便的語法get_value(some_function(some_object))

+0

什麼是錯的'模板 constexpr富增加(富常量&)'? –

回答

1

increase()必須constexpr

template <int N> 
struct Foo 
{ 
    static const int value = N; 
}; 

template <typename T> 
constexpr int get_value(T const &) 
{ 
    return T::value; 
} 

void huey() 
{ 
    Foo<3> three; 
    static_assert(get_value(three) == 3, ":("); 
} 

template <int N> 
constexpr Foo<N + 1> increase(Foo<N> const &) 
{ 
    return {}; 
} 

void dewey() 
{ 
    Foo<6> six; 
    static_assert(get_value(increase(six)) == 7, ":("); 
}