Я не вижу способа обеспечить, чтобы все типы Типы были типа T. Есть ли один?
Я не понимаю, из вашего вопроса, если вы хотите, чтобы Types
являются выводимыми типами шаблонов, и все они выводятся точно как T
, или если вы хотите конструктор без шаблона, который получает точность N
значений типа T
.
Первый случай прост (если вы можете использовать свертывание шаблона C ++ 17; в противном случае немного сложнее), потому что вы можете использовать std::is_same
template <typename ... Types,
typename std::enable_if<(sizeof...(Types) == N)
&& (... && std::is_same<Types, T>::value), int>::type = 0>
explicit HasArray(Types ... s) : arr {{ s... }}
{ }
Для второго случая я предлагаю вариантРешение Jarod42, которое использует специализацию HasArray
вместо промежуточного класса (редактирование: добавлено улучшение от самого Jarod42; спасибо!):
template<typename T, std::size_t N, typename = std::make_index_sequence<N>>
struct HasArray;
template<typename T, std::size_t N, std::size_t ... Is>
struct HasArray<T, N, std::index_sequence<Is...>>
{
static_assert( sizeof...(Is) == N , "wrong sequence size" );
protected:
std::array<T, N> arr;
public:
explicit HasArray(getType<T, Is> ... s) : arr {{ s... }}
{ }
};
, где getType
равно
template <typename T, std::size_t>
using getType = T;
В первом случае
HasArray<std::uint32_t, 2> foo(7, 13);
выдает ошибку компиляции, поскольку 7
и 13
выводятся как int
, что не std::uin32_t
.
Во втором случае этокомпиляция, потому что HasArray
имеет конструктор
HasArray(std::uint32_t, std::uint32_t)
и int
s конвертируютсяed std::uint32_t
.
Ниже приведен пример полной компиляции C ++ 14 для второго случая
#include <array>
#include <cstdint>
#include <type_traits>
template <typename T, std::size_t>
using getType = T;
template<typename T, std::size_t N, typename = std::make_index_sequence<N>>
struct HasArray;
template<typename T, std::size_t N, std::size_t ... Is>
struct HasArray<T, N, std::index_sequence<Is...>>
{
static_assert( sizeof...(Is) == N , "wrong sequence size" );
protected:
std::array<T, N> arr;
public:
explicit HasArray(getType<T, Is> ... s) : arr {{ s... }}
{ }
};
int main ()
{
HasArray<std::uint32_t, 2> foo(7, 13);
}