mardi 2 août 2016

Test if calling f(x) is possible using metaprogramming

The Stroustrup's book provides an example how to answer the question: "is it possible to call f(x) if x is of type X" (the section 28.4.4 "Further examples with Enable_if"). I've tried to reproduce the example but got something wrong and can't understand what.

In my code below, there is a function f(int). I expect that then the result of has_f<int>::value is 1 (true). The actual result is 0 (false).

#include <type_traits>
#include <iostream>

//
// Meta if/then/else specialization
//
struct substitution_failure { };

template<typename T>
struct substitution_succeeded : std::true_type { };

template<>
struct substitution_succeeded<substitution_failure> : std::false_type { };

//
// sfinae to derive the specialization
//
template<typename T>
struct get_f_result {
private:
  template<typename X>
    static auto check(X const& x) -> decltype(f(x));
  static substitution_failure check(...);
public:
  using type = decltype(check(std::declval<T>()));
};

//
// has_f uses the derived specialization
//
template<typename T>
struct has_f : substitution_succeeded<typename get_f_result<T>::type> { };

//
// We will check if this function call be called,
// once with "char*" and once with "int".
//
int f(int i) {
  std::cout << i;
  return i;
}

int main() {
  auto b1{has_f<char*>::value};
  std::cout << "test(char*) gives: " << b1 << std::endl;
  std::cout << "Just to make sure we can call f(int): ";
  f(777);
  std::cout << std::endl;
  auto b2{has_f<int>::value};
  std::cout << "test(int) gives: " << b2 << std::endl;
}

The output:

test(char*) gives: 0
Just to make sure we can call f(int): 777
test(int) gives: 0

Aucun commentaire:

Enregistrer un commentaire