Ant*_*ier 6 c++ sfinae template-function c++14 c++17
我想知道这个代码有什么区别:
#include <type_traits>
#include <iostream>
template<typename T> using is_ref = std::enable_if_t<std::is_reference_v<T>, bool>;
template<typename T> using is_not_ref = std::enable_if_t<!std::is_reference_v<T>, bool>;
template<typename T, is_ref<T> = true>
void foo(T&&) {
std::cout << "ref" << std::endl;
}
template<typename T, is_not_ref<T> = true>
void foo(T&&) {
std::cout << "not ref" << std::endl;
}
int main() {
int a = 0;
foo(a);
foo(5);
}
Run Code Online (Sandbox Code Playgroud)
而这个不起作用:
#include <type_traits>
#include <iostream>
template<typename T> using is_ref = std::enable_if_t<std::is_reference_v<T>, bool>;
template<typename T> using is_not_ref = std::enable_if_t<!std::is_reference_v<T>, bool>;
template<typename T, typename = is_ref<T>>
void foo(T&&) {
std::cout << "ref" << std::endl;
}
template<typename T, typename = is_not_ref<T>>
void foo(T&&) {
std::cout << "not ref" << std::endl;
}
int main() {
int a = 0;
foo(a);
foo(5);
}
Run Code Online (Sandbox Code Playgroud)
typename = is_ref<T>和之间的真正区别是is_ref<T> = true什么?
Bar*_*rry 12
如果删除默认模板参数,则会清楚区别的是什么.函数声明不能在不同的只是它们的默认值.这是不正确的:
void foo(int i = 4);
void foo(int i = 5);
Run Code Online (Sandbox Code Playgroud)
同样,这是不正确的:
template <typename T=int> void foo();
template <typename T=double> void foo();
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,你的第一个案例:
template<typename T, is_ref<T>>
void foo(T&&);
template<typename T, is_not_ref<T>>
void foo(T&&);
Run Code Online (Sandbox Code Playgroud)
这里的两个声明是唯一的,因为第二个模板参数在两个声明之间不同.第一个具有非类型模板参数,其类型为std::enable_if_t<std::is_reference_v<T>, bool>,第二个具有类型为的非类型模板参数std::enable_if_t<!std::is_reference_v<T>, bool>.那些是不同的类型.
然而,你的第二个案例:
template<typename T, typename>
void foo(T&&);
template<typename T, typename>
void foo(T&&)
Run Code Online (Sandbox Code Playgroud)
这显然是相同的签名 - 但我们只是重复它.这是不正确的.