ある変数がメソッドを呼び出せるかで SFINAE

auto func(...) -> decltype(...) を使えば, 渡された変数がメソッドを持つか持たないかで SFINAE とかできる.

#include <iostream>

struct memory {
  std::string to_string() const {
    return "is memory.";
  }
};

struct device {
  std::string to_string() const {
    return "is device.";
  }
};

template<class T>
auto get_string(T const& t) -> decltype(t.to_string()) {
  return t.to_string();
}

std::string get_string(...) {
  return "other instance.";
}

int main() {
  std::cout << get_string(0) << std::endl;
  std::cout << get_string("hoge") << std::endl;
  std::cout << get_string(memory()) << std::endl;
  std::cout << get_string(device()) << std::endl;
}

実行結果>

other instance.
other instance.
is memory.
is device.

実行環境
GCC 4.6.3 C++11 mode (-std=gnu++0x or -std=c++0x)
GCC 4.7.1 C++11 mode (-std=gnu++11 or -std=c++11)