static_assert
のために関数が指定されたテンプレート引数に対して有効かどうかをテストするのに、detection idiom(または別の方法)を使用する方法はありますか?関数が失敗した場合の慣性検出static_assert
例を以下に意図したように(戻り型計算を失敗)foo
の妥当性が検出されたことを示しているが、bar
のそれは(static_assert
に失敗する)ではありません。
#include <iostream>
#include <type_traits>
template <typename... T> using void_t = void;
template <class AlwaysVoid, template<class...> class Op, class... Args>
struct detector: std::false_type { };
template <template<class...> class Op, class... Args>
struct detector<void_t<Op<Args...>>, Op, Args...>: std::true_type { };
template <template<class...> class Op, class... Args>
constexpr bool is_detected = detector<void, Op, Args...>::value;
template <typename T>
std::enable_if_t<!std::is_void<T>::value> foo() {
std::cout << "foo" << std::endl;
}
template <typename T>
void bar() {
static_assert(!std::is_void<T>::value);
std::cout << "bar" << std::endl;
}
template <typename T> using foo_t = decltype(foo<T>());
template <typename T> using bar_t = decltype(bar<T>());
int main(int argc, char* argv[]) {
foo<int>();
// foo<void>(); // fails as expected
bar<int>();
// bar<void>(); // fails as expected
std::cout << std::boolalpha;
// detection works for foo
std::cout << is_detected<foo_t,int > << std::endl; // true
std::cout << is_detected<foo_t,void> << std::endl; // false
// but not for bar
std::cout << is_detected<bar_t,int > << std::endl; // true
std::cout << is_detected<bar_t,void> << std::endl; // true !!!
}
これはboost::lexical_cast
は、与えられた型に対して有効である場合、私は検出できない理由です。