gpt4 book ai didi

c++ - 重载,使用右值引用,类模板的构造函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:15:27 25 4
gpt4 key购买 nike

虽然最初它似乎是 working ,当通过 maker 函数调用时(进行模板参数推导),存在两个重载,一个是 T const& 一个是 T&& breaks compilation :

#include <iostream>
#include <utility>
#include <functional>

using namespace std;

// -----------------------------------------------
template<typename T, typename F>
struct Test
{
T m_resource;
F m_deleter;

Test(T&& resource, F&& deleter)
: m_resource(move(resource)), m_deleter(move(deleter))
{
}
Test(T const& resource, F const& deleter)
: m_resource(resource), m_deleter(deleter)
{
}
};
// -----------------------------------------------

// -----------------------------------------------
template<typename T, typename F>
Test<T, F> test(T&& t, F&& f)
{
return Test<T, F>(move(t), move(f));
}
template<typename T, typename F>
Test<T, F> test(T const& t, F const& f)
{
return Test<T, F>(t, f);
}
// -----------------------------------------------

int main()
{
// construct from temporaries --------------------
Test<int*, function<void(int*)>> t(new int, [](int *k) {}); // OK - constructor
auto tm = test(new int, [](int *k){}); // OK - maker function
// -----------------------------------------------

// construct from l-values -----------------------
int *N = new int(24);
auto F = function<void(int*)>([](int *k){});

Test<int*, function<void(int*)>> tt(N, F); // OK - construction
auto m = test(N, F); // Error - maker function
// -----------------------------------------------

return 0;
}

有什么想法吗?

最佳答案

template<typename T, typename F>
Test<T, F> test(T&& t, F&& f)
{
return Test<T, F>(move(t), move(f));
}

这个函数模板有两个参数,它们是通用引用template-type-parameter && 形式的函数模板参数遵守特殊推导规则:如果参数是左值,则模板类型参数被推导为左值引用类型。如果参数是右值,则推导的类型不是引用。

auto m = test(N, F);

int* Nfunction<void(int*)> F是左值,因此对于上面的函数模板,T推导为 int*&F推导为 function<void(int*)>& .引用折叠适用,参数 T&&变成 int*& &&并折叠为 int*& (与 F&& 类似)。

因此,您的类模板是使用引用类型( T == int*&F == function<void(int*)>& )实例化的。在类模板中,

Test(T&& resource, F&& deleter)
Test(T const& resource, F const& deleter)

将产生相同的签名,因为 int*& &&int*& const&都折叠到 int*& , 同样适用于 F .


注意一个带参数的函数int*&优于带有参数 int* const& 的函数当参数不是 const 时。因此,函数模板

template<typename T, typename F>
Test<T, F> test(T const& t, F const& f)

不会在出现错误的行中使用。一般来说,通用引用参数非常贪婪。

典型的解决方案是使用完美转发,如Jonathan Wakely 中所述。的 answer .

关于c++ - 重载,使用右值引用,类模板的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24755451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com