我有一个可以基于单个尺寸参数进行模板化的类。我想有一个构造函数,它根据模板大小参数接受可变数量的std::array
。所以,如果这个类被模板化为一个。它应该接受一个数组。如果模板化为2,它应该接受两个等。
这是我提出的,但显然它不起作用:
template<std::size_t V>
class Test
{
public:
/* Constructors. */
Test() {}
template <std::array<int, 3> ...Args, typename = typename std::enable_if<V == sizeof...(Args), void>::type>
Test(std::array<int, 3>&&... args)
{
}
};
int main()
{
auto t = Test<1>({ 1, 2, 3 });
auto t2 = Test<2>(
{ 1, 2, 3 },
{ 4, 5, 6 }
);
}
我收到的错误是:
error C2993: 'std::array<int,3>': illegal type for non-type template parameter 'Args'
note: see reference to class template instantiation 'Test<V>' being compiled
error C3543: 'std::array<int,3> &&': does not contain a parameter pack
error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'Test<1>'
note: No constructor could take the source type, or constructor overload resolution was ambiguous
error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'Test<2>'
note: No constructor could take the source type, or constructor overload resolution was ambiguous
感谢任何帮助。
答案 0 :(得分:2)
有了继承,你可以这样做:
template <std::size_t, typename T> using alwaysT = T;
template <typename T, typename Seq> struct TestHelper;
template <typename T, std::size_t ... Is>
struct TestHelper<T, std::index_sequence<Is...>>
{
TestHelper(alwaysT<Is, T>... arr) {}
};
template<std::size_t V>
class Test : TestHelper<const std::array<int, 3>&, std::make_index_sequence<V>>
{
public:
using TestHelper<const std::array<int, 3>&, std::make_index_sequence<V>>::TestHelper;
Test() = default;
};
答案 1 :(得分:1)
评论中的一些有效解决方案:
#include <type_traits>
#include <array>
template<typename... TArgs> struct
contains_only_array_of_3_int
{
static constexpr bool const value{false};
};
template<typename TBack> struct
contains_only_array_of_3_int<TBack>
{
static constexpr bool const value
{
::std::is_same<::std::array<int, 3>, TBack>::value
};
};
template<typename TFront, typename... TRest> struct
contains_only_array_of_3_int<TFront, TRest...>
{
static constexpr bool const value
{
contains_only_array_of_3_int<TFront>::value
&&
contains_only_array_of_3_int<TRest...>::value
};
};
template<std::size_t V> class
Test
{
public:
Test() {}
template <typename... TArgs>
Test(TArgs && ... args)
{
static_assert
(
sizeof...(TArgs) == V
, "arguments count mismatch"
);
static_assert
(
contains_only_array_of_3_int<::std::decay_t<TArgs>...>::value
, "arguments type mismatch"
);
}
};
int main()
{
Test<1> t
{
::std::array<int, 3>{ 1, 2, 3 }
};
Test<2> t2
{
::std::array<int, 3>{ 1, 2, 3 }
, ::std::array<int, 3>{ 4, 5, 6 }
};
Test<3> t3
{
::std::array<int, 3>{ 1, 2, 3 }
, ::std::array<int, 3>{ 4, 5, 6 }
, ::std::array<int, 3>{ 7, 8, 9 }
};
Test<3> t3_args_count_fail
{
::std::array<int, 3>{ 1, 2, 3 }
, ::std::array<int, 3>{ 4, 5, 6 }
};
Test<3> t3_args_tupe_fail
{
::std::array<int, 3>{ 1, 2, 3 }
, ::std::array<int, 2>{ 4, 5 }
, ::std::array<int, 3>{ 7, 8, 9 }
};
return(0);
}