C++ 重载,带有r值引用,类模板的构造函数
虽然最初似乎是,当通过maker函数调用(以进行模板参数推断)时,存在两个重载,一个是C++ 重载,带有r值引用,类模板的构造函数,c++,c++11,C++,C++11,虽然最初似乎是,当通过maker函数调用(以进行模板参数推断)时,存在两个重载,一个是T const&,另一个是T&&: #包括 #包括 #包括 使用名称空间std; // ----------------------------------------------- 样板 结构测试 { m_资源; F m_deleter; 测试(T&&resource、F&&deleter) :m_resource(move(resource)),m_deleter(move(deleter)) { } 测试
T const&
,另一个是T&&
:
#包括
#包括
#包括
使用名称空间std;
// -----------------------------------------------
样板
结构测试
{
m_资源;
F m_deleter;
测试(T&&resource、F&&deleter)
:m_resource(move(resource)),m_deleter(move(deleter))
{
}
测试(T常量和资源,F常量和删除器)
:m_resource(resource),m_deleter(deleter)
{
}
};
// -----------------------------------------------
// -----------------------------------------------
样板
测试(T&T、F&F)
{
返回测试(移动(t)、移动(f));
}
样板
测试(T常数和T,F常数和F)
{
回归试验(t,f);
}
// -----------------------------------------------
int main()
{
//从临时建筑--------------------
Test t(new int,[](int*k){});//确定-构造函数
auto tm=test(新的int,[](int*k){});//确定-maker函数
// -----------------------------------------------
//从l值构造-----------------------
int*N=新的int(24);
自动F=函数([](int*k){});
测试tt(N,F);//正常-构造
自动m=test(N,F);//错误生成器函数
// -----------------------------------------------
返回0;
}
有什么想法吗 我认为这是因为自动类型猜测失败了,因为这行代码说:
prog.cpp:18:2:error:'Test::Test(const T&,const F&)[with T=int*&;F=std::function&]'不能重载
编译器试图用int*&而不是int*实例化它。我很确定,如果您显式地指定类型(我理解您想要避免的),它会工作得很好
我真的不明白你为什么把这个放在你的maker函数中
Test<T, F> test(T&& t, F&& f)
{
return Test<T, F>(move(t), move(f));
}
测试测试(T&T,F&F)
{
返回测试(移动(t)、移动(f));
}
t
和f
已经是右值引用,所以您不需要对它们调用move我认为这是因为自动类型猜测失败了,因为这行代码说prog.cpp:18:2:error:'Test::Test(const t&,const f&)[with t=int*&;f=std::function&]'不能重载
编译器尝试使用int*&而不是int*来实例化它。我很确定,如果您显式地指定类型(我理解您想要避免的),它会工作得很好
template<typename T, typename F>
Test<T, F> test(T&& t, F&& f)
{
return Test<T, F>(move(t), move(f));
}
我真的不明白你为什么把这个放在你的maker函数中
Test<T, F> test(T&& t, F&& f)
{
return Test<T, F>(move(t), move(f));
}
测试测试(T&T,F&F)
{
返回测试(移动(t)、移动(f));
}
t
和f
已经是右值引用,因此不需要对它们调用move
template<typename T, typename F>
Test<T, F> test(T&& t, F&& f)
{
return Test<T, F>(move(t), move(f));
}
这将接受左值和右值的任意组合,它将确保您返回所需的类型,并且它将使用原始值类别将参数完美地转发给Test
构造函数
你应该读/看
这将接受左值和右值的任意组合,它将确保您返回所需的类型,并且它将使用原始值类别将参数完美地转发给Test
构造函数
你应该读/看
int*N
和函数F
是左值,因此对于上面的函数模板,T
被推导出int*&
,F
被推导出函数&
。引用折叠适用,参数T&&
变为int*&&&
,并折叠为int*&
(与F&
类似)
因此,使用引用类型(T==int*&
,F==function&
)实例化类模板。在类模板中
Test(T&& resource, F&& deleter)
Test(T const& resource, F const& deleter)
将产生相同的签名,因为int*&&&
和int*&&const&
都折叠为int*&
,对于F
也是如此
请注意,当参数不是常量时,带参数
int*&
的函数比带参数int*const&
的函数更可取。因此,函数模板
template<typename T, typename F>
Test<T, F> test(T const& t, F const& f)
模板
测试(T常数和T,F常数和F)
不会在出现错误的行中使用。一般来说,通用参考参数非常贪婪
典型的解决方案是使用中所述的完美转发
int*N
和函数F
是左值,因此对于上面的函数模板,T
被推导出int*&
,F
被推导出函数&
。引用折叠适用,参数T&&
变为int*&&&
,并折叠为int*&
(与F&
类似)
因此,使用引用类型(T==int*&
,F==function&
)实例化类模板。在类模板中
Test(T&& resource, F&& deleter)
Test(T const& resource, F const& deleter)
将产生相同的签名,因为int*&&&
和int*&&const&
都折叠为int*&
,对于F
也是如此
请注意,当参数不是常量时,带参数
int*&
的函数比带参数int*const&
的函数更可取。因此,函数模板
template<typename T, typename F>
Test<T, F> test(T const& t, F const& f)
模板
测试(T常数和T,F常数和F)
不会在出现错误的行中使用。一般来说,通用参考参数非常贪婪
典型的解决方案是使用s中所述的完美转发。“t
和f
已经是右值引用,因此不需要对它们调用move”t
和f
是变量(变量名称),因此,作为表达式,它们是左值表达式。否则,您可能会意外地离开它们两次。每一个出口