为什么SFINAE在函数重载时报错
Why SFINAE report error in function overloading
下面的代码编译不了,我只是想测试一下SFINAE,为什么编译不了?
#include <type_traits>
template<typename T>
class TestVoid {
template<std::enable_if_t<std::is_void_v<T>> * = nullptr>
void func() {
std::cout << "void\n";
}
template<std::enable_if_t<!std::is_void_v<T>> * = nullptr>
void func() {
std::cout << "none void\n";
}
};
int main() {
TestVoid<void> t;
return 0;
}
问题是 std::enable_if
的条件不依赖于 func
本身的模板参数。
您可以将代码更改为
template<typename T>
struct TestVoid {
template<typename X = T, std::enable_if_t<std::is_void_v<X>> * = nullptr>
void func() {
std::cout << "void\n";
}
template<typename X = T, std::enable_if_t<!std::is_void_v<X>> * = nullptr>
void func() {
std::cout << "none void\n";
}
};
实例化 class 模板时,所有成员函数声明都必须有效。在您的情况下,其中之一不会。相反,您可以将 func
委托给另一个函数模板。
template<typename T, std::enable_if_t<std::is_void_v<T>> * = nullptr>
void func() {
std::cout << "void\n";
}
template<typename T, std::enable_if_t<!std::is_void_v<T>> * = nullptr>
void func() {
std::cout << "none void\n";
}
template<typename T>
class TestVoid {
public:
void func_member() {
func<T>();
}
};
或者,如果您想将 func
的实际实现保留为成员函数:
template<typename T>
class TestVoid {
public:
void func_member() {
func<T>();
}
private:
template<typename U, std::enable_if_t<std::is_void_v<U>> * = nullptr>
void func() {
std::cout << "void\n";
}
template<typename U, std::enable_if_t<!std::is_void_v<U>> * = nullptr>
void func() {
std::cout << "none void\n";
}
};
下面的代码编译不了,我只是想测试一下SFINAE,为什么编译不了?
#include <type_traits>
template<typename T>
class TestVoid {
template<std::enable_if_t<std::is_void_v<T>> * = nullptr>
void func() {
std::cout << "void\n";
}
template<std::enable_if_t<!std::is_void_v<T>> * = nullptr>
void func() {
std::cout << "none void\n";
}
};
int main() {
TestVoid<void> t;
return 0;
}
问题是 std::enable_if
的条件不依赖于 func
本身的模板参数。
您可以将代码更改为
template<typename T>
struct TestVoid {
template<typename X = T, std::enable_if_t<std::is_void_v<X>> * = nullptr>
void func() {
std::cout << "void\n";
}
template<typename X = T, std::enable_if_t<!std::is_void_v<X>> * = nullptr>
void func() {
std::cout << "none void\n";
}
};
实例化 class 模板时,所有成员函数声明都必须有效。在您的情况下,其中之一不会。相反,您可以将 func
委托给另一个函数模板。
template<typename T, std::enable_if_t<std::is_void_v<T>> * = nullptr>
void func() {
std::cout << "void\n";
}
template<typename T, std::enable_if_t<!std::is_void_v<T>> * = nullptr>
void func() {
std::cout << "none void\n";
}
template<typename T>
class TestVoid {
public:
void func_member() {
func<T>();
}
};
或者,如果您想将 func
的实际实现保留为成员函数:
template<typename T>
class TestVoid {
public:
void func_member() {
func<T>();
}
private:
template<typename U, std::enable_if_t<std::is_void_v<U>> * = nullptr>
void func() {
std::cout << "void\n";
}
template<typename U, std::enable_if_t<!std::is_void_v<U>> * = nullptr>
void func() {
std::cout << "none void\n";
}
};