Tôi đã hỏi một câu hỏi khoảng một tuần trước để hỏi làm thế nào tôi có thể đơn giản khởi tạo một mẫu lớp chỉ khi kiểu nó đã có một hàm thành viên cụ thể. Trong câu trả lời của tôi, tôi đã nhận được một giải pháp phức tạp. Nhưng sau đó tôi đã cố gắng làm điều đó một mình. Tôi chỉ muốn biết nếu điều này đủ để tìm ra một loại nhất định T
có hàm void có tên là f
lấy 0 tham số.Đây có phải là SFINAE không?
#include <type_traits>
#include <utility>
template <typename T, typename = void>
struct has_f : std::false_type { };
template <typename T>
struct has_f<
T,
decltype(std::declval<T>().f(), void())> : std::true_type { };
template <typename T, typename = typename std::enable_if<has_f<T>::value>::type>
struct A { };
struct B
{
void f();
};
struct C { };
template class A<B>; // compiles
template class A<C>; // error: no type named ‘type’
// in ‘struct std::enable_if<false, void>’
Nếu vậy, tại sao là những câu trả lời khác rất phức tạp trong this thread?
Có, đây là SFINAE và có, điều này là đúng. Đối với lý do tại sao các câu trả lời khác phức tạp hơn ... khó nói. –
Để làm rõ 'has_f' tự dựa vào SFINAE,' A' thì không. –
Như một khả năng, SFINAE hỗ trợ trong một số trình biên dịch (* ho * MSVC2012) loại hút, vì vậy một số phức tạp đó có thể là giải pháp để có một SFINAE di động hơn. Là một sang một bên, 'std :: declval() .f()' và 'std :: declval () .f()' (hoặc là nó 'std :: declval () .f()'?) có thể là những thứ khác nhau trong C++ 1y do tham chiếu rvalue đối với tính năng 'this' này. –
Yakk