我有以下代码:
#include <iostream>
#include <type_traits>
template <typename T, typename std::enable_if
<std::is_convertible<int, T>::value, T>::type>
void func(T a)
{
std::cout << a << std::endl;
}
template <typename T, typename std::enable_if
<!std::is_convertible<int, T>::value, T>::type>
void func(T a)
{
a.print();
}
class Test
{
public:
void print()
{
std::cout << "Test" << std::endl;
}
};
int main()
{
func(3);
func("Test");
return 0;
}
使用这段代码,我希望第一次调用func
打印出3
(因为int
确实可以转换为int
,所以应该调用第一个专门化),第二次调用func
打印出test
(test()
不能转换为int
,所以应该调用第二个专门化)。但是,我反而得到了一个编译器错误:
prog.cpp:在函数“int main()”中:
prog.cpp:5:6:注意:模板参数扣减/替换失败:
prog.cpp:27:8:注意:无法推导出模板参数“[Anonymous>”
但是,如果我将模板化函数改为:
template <typename T, typename std::enable_if
<std::is_convertible<int, T>::value, T>::type* =
nullptr>
void func(T a)
{
std::cout << a << std::endl;
}
template <typename T, typename std::enable_if
<!std::is_convertible<int, T>::value, T>::type* =
nullptr>
void func(T a)
{
a.print();
}
然后一切都按照我的期望编译和工作。这个额外的语法在做什么?我为什么需要它?
template<typename T, typename std::enable_if<std::is_convertible<int, T>::value, T>::type>
如果我们要消除噪音,就会变成
template<typename T, typename Something<T>::type>
这里的typename
指定嵌套的type
是一个类型的名称。有关更多信息,请参见此处。
在第一种情况下,第二个参数是非类型的,因此函数调用func(3)
不适合需要func
的模板。
我正在构建一些输入检查器,需要为整数和/或双精度设置特定的函数(例如,“iPrime”应该只适用于整数)。 如果我使用作为参数,它工作得很好: 但如果我将其用作模板参数(如上所示)http://en.cppreference.com/w/cpp/types/enable_if ) 那么我有以下错误: 我不知道第二个版本出了什么问题。
我发现了和类型推导的以下行为,这对我来说是意想不到的: 中的两行都会导致错误: 没有函数模板“stdfunc_test”的实例与参数列表匹配 尝试在Visual Studio 2015中编译时。 为什么类型演绎不从函数类型中演绎模板类型,有没有变通方法?
Stroustrup C++第4版第796页指出 “如果的条件计算为,则完全忽略它所在的整个函数声明。”和“...我们不申报任何东西。”。 我也读过这个建议的线程,在这个线程中,SFINAE只有在模板参数的参数推导中的替换使构造格式不正确时才起作用。
多亏了C11,我们收到了系列的仿函数包装器。不幸的是,我一直只听到关于这些新添加的不好的消息。最受欢迎的是它们非常慢。我测试了它,与模板相比,它们真的很糟糕。 111毫秒对1241毫秒。我认为这是因为模板可以很好地内联,而通过虚拟调用覆盖内部。 显然,在我看来,模板也有其问题: 它们必须以头的形式提供,这不是您在以封闭代码形式发布库时可能不希望做的事情, 因此,我可以假设s可以用作传递函子的事实标
考虑代码: Microsoft Visual Studio 2013给出以下错误: C2912:显式特化'CByteArray序列化(const HLVariant 错误C2783:“CByteArray serialize(const std::enable_if::type 错误表明没有
我在旧版本的C Cookbook中看到了这段代码,这让我很困惑。这似乎是编译,但我不知道为什么代码会这样写。 T()是什么意思?这是std::accumulate的init参数——开始求和的值。我编写了一个版本,其中我将double()替换为T()(以“硬连线”模板),然后它进行编译。double()是什么意思?