太长的评论 - C++ 11 方法有什么问题?
#include <array>
#include <cstddef>
template < std::size_t t_dim >
constexpr std::array<int, t_dim> init()
{
static_assert(false, "Unknown # of dimensions");
return {};
}
template <>
constexpr std::array<int, 2> init<2>()
{
return {1, 2};
}
template <>
constexpr std::array<int, 3> init<3>()
{
return {1, 2, 3};
}
void function()
{
std::array<int, nDim> a = init<nDim>();
}
int main()
{
function();
}
编辑:使用本地类型的方法
Edit2:使用非类型模板参数包来简化声明语法。
Edit3:简化(将初始化值存储为非类型模板参数后可以删除 SFINAE)。
Edit4:结合第一种和以前的方法,使语法更容易使用,并再次允许无效的类型作为非类型模板参数。
警告:黑色丑陋的模板魔法
#include <array>
#include <cstddef>
#include <algorithm>
#include <iostream>
#include <iterator>
constexpr std::size_t nDim = 3;
template < typename TArr >
struct stdarray_extent
{
static std::size_t const value = TArr{}.size();
};
template < bool t_if, typename T_Then, typename T_Else >
struct type_if
{
using type = T_Then;
};
template < typename T_Then, typename T_Else >
struct type_if < false, T_Then, T_Else >
{
using type = T_Else;
};
template < std::size_t t_dim, typename T, typename... TT >
struct init_
: init_ < t_dim, TT... >
{
using base = init_ < t_dim, TT... >;
static bool constexpr valid = ( stdarray_extent<T>::value == t_dim
? true : base::valid);
using type = typename type_if < stdarray_extent<T>::value == t_dim,
T, typename base::type
> :: type;
template < typename TF, typename... TTF >
static constexpr
typename std::enable_if< stdarray_extent<TF>::value == t_dim, type >::type
get(TF&& p, TTF&&... pp)
{
return p;
}
template < typename TF, typename... TTF >
static constexpr
typename std::enable_if< stdarray_extent<TF>::value != t_dim, type>::type
get(TF&& p, TTF&&... pp)
{
return base::get( std::forward<TTF>(pp)... );
}
};
template < std::size_t t_dim, typename T >
struct init_ < t_dim, T >
{
static bool constexpr valid = (stdarray_extent<T>::value == t_dim);
using type = typename type_if < stdarray_extent<T>::value == t_dim,
T,
std::array<typename T::value_type, t_dim>
> :: type;
template < typename TF >
static constexpr
typename std::enable_if< stdarray_extent<TF>::value == t_dim, type>::type
get(TF&& p)
{
return p;
}
template < typename TF >
static constexpr
typename std::enable_if< stdarray_extent<TF>::value != t_dim, type>::type
get(TF&& p)
{
return {};
}
};
template < std::size_t t_dim, typename... TT >
auto init(TT&&... pp)
-> decltype( init_<t_dim, TT...>::get(std::forward<TT>(pp)...) )
{
static_assert( init_<t_dim, TT...>::valid, "Unknown # of Dimensions" );
return init_<t_dim, TT...>::get(std::forward<TT>(pp)...);
}
void function()
{
constexpr std::size_t nDim = 3;
std::array<int, nDim> a = init<nDim>( std::array<int,2>{{1,2}},
std::array<int,3>{{3,2,1}} );
// output
std::copy( std::begin(a), std::end(a),
std::ostream_iterator<int>{std::cout, ", "} );
}
int main()
{
function();
}