How to strictly prohibit the transfer to the template function arguments of non-integer types? Found such a solution:

template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>> void foo(T t) { } 

But you can hack it by specifying the second template type explicitly:

 f<double, void>(3.14); 

    3 answers 3

    Can it just go like that?

     template <typename T> void foo(T t) { static_assert(std::is_integral<T>::value, "Integer required."); } 

      This is not a hack, but a shot in the leg. It's like a #define private public . It seems to be compiled and maybe even works, but nothing good will come of it.

      Some people even take the view that it’s enough to write this:

       /// \bief Функция /// \param[in] t Аргумент /// \warning Допускаются только целочисленные аргументы template <class T> void foo(T t) { } 

      And that will be enough.

      But if you answer your question, you can hide enable_if in the function body:

       template <typename T> void foo(T t) { typedef typename std::enable_if<std::is_integral<T>::value>::type Dummy; } 

      PS: However, if a person has firmly set himself the goal of passing you a double to the function, nothing will stop him:

       #include <type_traits> namespace std{ template<> struct is_integral<double>{ static const bool value = true; }; } template <typename T> void foo(T t) { typedef typename std::enable_if<std::is_integral<T>::value>::type Dummy; } int main() { foo(3.14); } 

      So I recommend you not to worry too much about the "hacks." As long as there is a preprocessor and specialization of templates, you will not be able to protect 100%

      • The focus with the is_integral specialization, at least in VC ++, does not work. - Harry
      • @Harry, I do not have a visual on hand to check. What mistake? This online compiler chewed everything normally. - yrHeTaTeJlb
      • Yeah, Hochma is that I had <iostream> turned on. If you turn it off, it passes. In a word, it is necessary that this is_integral created first ... However, since all these templates go in the source code, you can not pervert, but simply edit the source itself :) - Harry
      • @Harry, I added iostream and it works for me :) Give a code that does not compile for your experiments - yrHeTaTeJlb

      For example:

       template <typename T> void foo(T t) { std::enable_if_t<std::is_integral<T>::value> g(); } 

      or there

       template <typename T> void foo(T t) { std::enable_if_t<std::is_integral<T>::value> * g; } 

      Well, i.e. it is somehow "not good" to use enable_if_t , where type presence is required.

       template <typename T> void foo(T t) { using nafig = std::enable_if_t<std::is_integral<T>::value>; } 

      Or, as they did before enable_if_t :

       template <typename T> void foo(T t) { int g[std::is_integral<T>::value]; } 
      • Not necessary to use enable_if_t , is there another solution? - user226011
      • You can use the old trick - declare an array of size std::is_integral<T>::value ... - Harry
      • why do we need is_integral in an array? + I don’t really want to allocate extra memory - user226011
      • Then don't worry about someone hacking your code :) - Harry