Can C ++ enable_if implement by default?

I want to write a function printthat behaves differently depending on the type of argument.

Here is my implementation:

template <typename T, typename std::enable_if<std::is_array<T>::value, int>::type = 0>
void print(const T &v) {
  std::cout << "array: ";
  for (const auto &e : v) {
    std::cout << e << ", ";
  }
  std::cout << std::endl;
}

template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void print(const T &v) {
  std::cout << "integral: " << v << std::endl;
}

template <typename T, typename std::enable_if<!(std::is_array<T>::value || std::is_integral<T>::value), int>::type = 0>
void print(const T &v) {
  std::cout << "default: " << v << std::endl;
}

This code works as expected, but the conditions in the latest specification are too complex.

Is there any solution to simplify the latter?

+4
source share
2 answers

The general approach that you can use for the default case is to have a function that takes a list of variable arguments. This will be used only if no other function matches. Here is an example:

template <typename T, typename std::enable_if<std::is_array<T>::value, int>::type = 0>
void print_helper(const T &v,int) {
  std::cout << "array: ";
  for (const auto &e : v) {
    std::cout << e << ", ";
  }
  std::cout << std::endl;
}

template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void print_helper(const T &v,int) {
  std::cout << "integral: " << v << std::endl;
}

template <typename T>
void print_helper(const T &v,...) {
  std::cout << "default: " << v << std::endl;
}

template <typename T>
void print(const T &v)
{
  print_helper(v,0);
}

, , .

+4

, , Xeo:

struct otherwise{ otherwise(...){} };

template<unsigned I>
struct choice : choice<I+1>{};

// terminate recursive inheritence at a convenient point,
// large enough to cover all cases
template<> struct choice<10>{};

, , :

// just forward to our first choice
template <class T> void print(const T &v) { print(v, choice<0>{}); }

- :

template <class T, class = std::enable_if_t<std::is_array<T>::value>>
void print(const T& v, choice<0> ) { ... }

:

template <class T, class = std::enable_if_t<std::is_integral<T>::value>>
void print(const T& v, choice<1> ) { ... }

-

template <class T>
void print(const T& v, otherwise ) { ... }

.

+1

All Articles