If you can use C++17 (but you tagged C++11 and C++14 only) a if constexpr
solution based (very elegant the lambda based from Evg) is preferable, IMHO.
Before C++17, I suppose you can try using SFINAE. By example
#include <type_traits>
template <int N>
struct Foo
{
static constexpr int v1 = {};
static constexpr long v2 = {};
template <int M = N>
constexpr static std::enable_if_t<M % 2 == 1, int> getV3 ()
{ return v1; }
template <int M = N>
constexpr static std::enable_if_t<M % 2 != 1, long> getV3 ()
{ return v2; }
static constexpr auto v3 = getV3();
};
int main ()
{
static_assert( std::is_same_v<int const, decltype(Foo<1>::v3)> );
static_assert( std::is_same_v<long const, decltype(Foo<2>::v3)> );
}
As suggested by Evg (thanks!) you can avoid SFINAE using overloading (good-old tag dispatching). By example
template <int N>
struct Foo
{
static constexpr int v1 = {};
static constexpr long v2 = {};
constexpr static auto getV3 (std::true_type)
{ return v1; }
constexpr static auto getV3 (std::false_type)
{ return v2; }
static constexpr auto v3 = getV3(std::integral_constant<bool, N%2>{});
};