Có cách nào để sử dụng detection idiom (hoặc phương pháp khác) để kiểm tra xem một hàm có hợp lệ đối với các đối số mẫu đã cho hay không, nếu nó không thành công do static_assert
?Phát hiện thành ngữ có chức năng không static_assert
Ví dụ dưới đây minh họa rằng tính hợp lệ của foo
(không tính toán loại trả về) được phát hiện như dự định, nhưng của bar
(không static_assert
) thì không.
#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 !!!
}
Đây là lý do tôi không thể phát hiện nếu một boost::lexical_cast
hợp lệ cho các loại nhất định.