Let there be such a construction:

template<typename T> class SomeClass { template<typename... Args> SomeClass(Args& ...args) {} }; 

How can one “persuade” the compiler to accept only identical types in a package, and how to indicate a specific type (for example, double)?

1 answer 1

Issue resolved

The reading “C ++ Programming Language. Lectures and Exercises. 6th edition, 2012, Siven Pratt” helped.

The technique, as it turned out, is unpretentious - recursive unpacking and receipt of each argument of the pack. It turned out two options, but with static_assert'om, IMHO, better - more meaningful output. As an experiment, we check the arguments for std :: size_t compliance.

Option 1 (static_assert):

 #include <type_traits> #include <iostream> #include <vector> //////////////////////////////////////////////////////////////////// // Пример проверки передачи беззнаковых аргументов в конструктор // Вариант 1 (используем static_assert) //////////////////////////////////////////////////////////////////// template<typename T> class SomeClass { public: template<typename... Args> SomeClass(const Args& ...args) { UnPack(args... ); } private: template<typename First, typename... Last> void UnPack(const First& F, const Last&... L) { UnPack(F); UnPack(L...); } template<typename First> void UnPack(const First& Value) { static_assert(std::is_same<First,std::size_t>::value,"Type mismatch!"); std::cout << Value << ":"; } }; int main() { // норм - передаётся нужный тип std::size_t i=1,j=2,k=3; SomeClass<int> S1(i,j,k); // норм - передаются беззнаковые константы SomeClass<std::string> S2(1u,2u,3u); // фэйл - знаковые типы не проходят // int a=1,b=2,c=3; // SomeClass<bool> S3(a,b,c); return 0; } 

Option 2 (std :: enable_if):

 #include <type_traits> #include <iostream> #include <vector> //////////////////////////////////////////////////////////////////// // Пример проверки передачи беззнаковых аргументов в конструктор // Вариант 2 (используем std::enable_if) //////////////////////////////////////////////////////////////////// template<typename T> class SomeClass { public: template<typename... Args> SomeClass(const Args& ...args) { UnPack(args... ); } private: template<typename First, typename... Last> void UnPack(const First& F, const Last&... L) { UnPack(F); UnPack(L...); } template<typename First> void UnPack(const First& Value, typename std::enable_if<std::is_same<First,std::size_t>::value>::type* = 0) { std::cout << Value << ":"; } }; int main() { // норм - передаётся нужный тип std::size_t i=1,j=2,k=3; SomeClass<int> S1(i,j,k); // норм - передаются беззнаковые константы SomeClass<std::string> S2(1u,2u,3u); // фэйл - знаковые типы не проходят // int a=1,b=2,c=3; // SomeClass<bool> S3(a,b,c); return 0; } 

In principle, the issue is resolved. However, if there are more elegant options - velcom! :)