C++ 为什么SFINAE不能与std::enable_if_t一起工作? #包括 #包括 #包括 模板 < 类型名T, 模板类别C, typename=std::启用 < std::值是否相同 > > 空f(常数C和coll) { 标准::cout 空f(常数C和coll) { std::cout
默认模板参数不参与函数匹配。C++ 为什么SFINAE不能与std::enable_if_t一起工作? #包括 #包括 #包括 模板 < 类型名T, 模板类别C, typename=std::启用 < std::值是否相同 > > 空f(常数C和coll) { 标准::cout 空f(常数C和coll) { std::cout,c++,c++11,templates,sfinae,template-templates,C++,C++11,Templates,Sfinae,Template Templates,默认模板参数不参与函数匹配。 从编译器的角度来看,当它试图寻找合适的函数时,两者都具有以下特征: #include <vector> #include <list> #include <iostream> template < typename T, template<typename, typename = std::allocator<T>> class C, typename = std::enab
从编译器的角度来看,当它试图寻找合适的函数时,两者都具有以下特征:
#include <vector>
#include <list>
#include <iostream>
template
<
typename T,
template<typename, typename = std::allocator<T>> class C,
typename = std::enable_if_t
<
std::is_same<std::vector<T>, C<T>>::value
>
>
void f(const C<T>& coll)
{
std::cout << "vector" << std::endl;
}
template
<
typename T,
template<typename, typename = std::allocator<T>> class C,
typename = std::enable_if_t
<
std::is_same<std::list<T>, C<T>>::value
>
>
void f(const C<T>& coll)
{
std::cout << "list" << std::endl;
}
int main()
{
std::vector<int> c1{ 1, 2, 3 };
std::list<int> c2{ 1, 2, 3 };
f(c1);
f(c2);
}
编译器如何确定要调用的f
在代码中或多或少也会发生相同的情况
将enable\u if\u t
移动到返回类型,它将按预期工作。在这种情况下,由于一个错误,替换将排除两个定义中的一个(正如sfinae表达式所预期的那样)。为什么需要sfinae?一个简单的重载就足够了
template<typename = void>
void f() {}
template<typename = char>
void f() {}
// ...
f<>();
模板
空f(常数std::vector和coll)
{
std::您是否可以尝试使用非类型模板参数,如enable\u if\u t*=nullptr
?我已经尝试过,但结果是相同的。我认为它应该与非类型模板参数一起工作。此代码格式不正确。您需要有通用实现并专门用于容器类型哦还有一件事std::enable\u if\t
可用,因为c++14不能总是将enable\u if\t
移动到返回类型(构造函数/转换运算符)另一方面,由于c++11始终可以使用带有默认值的非类型模板参数,这就是为什么我更喜欢这个参数,但我非常喜欢您的解释+1@W.F.我明白你的意思。在这种情况下,返回类型是一个可行的解决方案,这就是我提到它的原因。仅此而已。-)这并不能回答为什么它不起作用的问题?@skypjack:修复了。谢谢!所以我把它也标记为副本。
template<typename = void>
void f() {}
template<typename = char>
void f() {}
// ...
f<>();
template <typename T>
void f(const std::vector<T>& coll)
{
std::cout << "vector" << std::endl;
}
template < typename T>
void f(const std::list<T>& coll)
{
std::cout << "list" << std::endl;
}
int main()
{
std::vector<int> c1{ 1, 2, 3 };
std::list<int> c2{ 1, 2, 3 };
f(c1);
f(c2);
}
template
<
typename T,
template<typename, typename = std::allocator<T>> class C,
typename std::enable_if_t
<
std::is_same<std::list<T>, C<T>>::value
>* = nullptr
>
void f(const C<T>& coll);