2016-07-15 19 views
0

kann ich eine constexpr Funktion schreiben, die Abzug führt geben jedoch nicht die an sie übergeben Objekt verwenden:Convenient constexpr-Funktion

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, ":("); 
} 

Wenn jedoch das Argument get_value das Ergebnis einer anderen Operation ist, diese Ansatz versagt:

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

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

Der Compiler (zu Recht) beklagt, dass increase(six) nicht ein konstanter Ausdruck ist. Ich kann dies wie folgt beheben:

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

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

aber ich weiß nicht, wie die zusätzlichen decltype -Gymnastik. Ich könnte ein Makro einführen:

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

aber ich möchte, wenn möglich, Makros vermeiden. Gibt es eine Möglichkeit, die bequeme Syntax get_value(some_function(some_object)) ohne Makros zu ermöglichen?

+0

zu sein, was mit 'template constexpr Foo Anstieg (Foo const &)' falsch ist? –

Antwort

1

increase() braucht constexpr zu

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, ":("); 
}