There are a lot of similar questions to this one, but specifically to a question like mine, I didn’t quite find the answer.

How to make a function with a variable number of arguments of one specific type? Let it be char. That is, so that it can be called with any number of arguments, but so that they all must be char. Otherwise, an error at compile time. So is it possible to do?

foo(char, char, char); //---Можно! foo(char); //--Можно! foo(char, char, int) //--Нельзя, ошибка на этапе компиляции foo() //==По-хорошему, тоже надо бы запретить, но не это главное 
  • Than the variant with an array does not suit? - PinkTux
  • Foo (char a ...); - user31238
  • @ user31238, and what's wrong with writing Foo('a', -12345678) ? "Read" - just about, read the question first. - PinkTux
  • Read about functions with a variable number of parameters - user31238

3 answers 3

If you have C ++ 11 you can do this:

 #include <iostream> #include <type_traits> template<class ...Args> struct Dummy{}; template<class T, class ...Args, class = Dummy<typename std::enable_if<std::is_same<T, Args>::value>::type...>> void foo(const T &arg, const Args &...args){ } int main(){ int i = 0; double d = 0; foo(i, i); //ok foo(d, d); //ok //foo(i, d); //error } 

If you know the type in advance, replace T with this type.

  • I like this option, I didn't even think about that. - ixSci

You can do, for example, like this:

 #include <iostream> #include <type_traits> #include <initializer_list> using namespace std; template<typename T> constexpr bool allChars() { return is_same<char, T>::value; } template<typename T1, typename T2, typename... Tail> constexpr bool allChars() { return is_same<char, T1>::value ? allChars<T2, Tail...>() : false; } template<typename... Chars> enable_if_t<allChars<Chars...>()> foo(Chars... rawChars) { initializer_list<char> chars{rawChars...}; for(auto character : chars) cout << character << '\n'; } int main() { foo('S', 'O'); return 0; } 
  • Intrigued by the return type :) And if you want something else? It is impossible to enable_if_t<allChars<Chars...>()> dummy(); enable... in the type parameters ... It is possible to declare only that in the body a dummy function like enable_if_t<allChars<Chars...>()> dummy(); ? - Harry
  • @Harry, well, there void by default. Can be replaced with anything: enable_if_t<allChars<Chars...>(), MyCoolType> - ixSci
  • Hmm, live and learn ... Thank you! - Harry
  • initializer_list can be inserted directly into for . - αλεχολυτ

The variant foo(char,...) does not pass in principle - because ... it is not automatically subject to any type checks.

The option of having a mass of overloads foo(char) , foo(char,char) and so on - in principle, you can use it, but no one will interfere with the implicit cast, such as calling f(3) .

The option on the verge of a foul - void foo(std::initializer_list<char> c) - does not fit exactly for the same reason ...

So "pure functions", it seems, will not work. It remains a sample version, but here we must think ... :)

PS While typing the answer, @ixSci has already done it for me :)