gpt4 book ai didi

c++ - 获取合适的存储值类型?

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

假设我们有一个类 Box 如下:

struct Base {}

template<typename T>
struct Box : Base
{
template<typename... Args>
Box(Args&&... args)
: t(forward<Args>(args)...)
{}

T t;
}

然后我们有一个函数 MakeBox:

template<typename X>
Base* MakeBox(X&& x)
{
return new Box<???>(forward<X>(x));
}

X 类型是从调用 MakeBox 时使用的参数推导出来的。

然后我们需要以某种方式从 X 计算出适当的“存储类型”参数 T。

我认为如果我们天真地使用:

    return new Box<X>(forward<X>(x));

那么这会引起问题。

显然 std::bindstd::function 需要处理这些问题,它们是如何处理的?

std::decay 在这里有帮助吗?

最佳答案

如果我理解正确你想要实现什么,那么你需要使用 std::decay .假设您提供一个 S 类型的对象至 MakeBox() , 通用引用 X&&将以这样的方式解析,使函数参数成为 S& 类型之一或 S&&取决于你的论点是(分别)左值还是右值。

为了实现这一点,并且由于通用引用的 C++11 规则,在第一种情况下,模板参数将被推导为 X=S&。 (此处 X 不能作为 Box<> 的参数,因为您的成员变量必须是对象而不是对象引用),而在第二种情况下,它将被推断为 X=S (此处 X 可以作为 Box<> 的参数)。通过申请std::decay您还将隐式应用 std::remove_reference到推导类型 X在将其作为模板参数提供给 Box<> 之前, 你要确保 X永远相等 S永远不会S& (请记住,X永远 将被推断为 S&& 在这里,它将是 SS& )。

#include <utility>
#include <type_traits>
#include <iostream>

using namespace std;

struct Base {};

template<typename T>
struct Box : Base
{
template<typename... Args>
Box(Args&&... args)
: t(forward<Args>(args)...)
{
}

T t;
};

template<typename X>
Base* MakeBox(X&& x)
{
return new Box<typename decay<X>::type>(forward<X>(x));
}

struct S
{
S() { cout << "Default constructor" << endl; }
S(S const& s) { cout << "Copy constructor" << endl; }
S(S&& s) { cout << "Move constructor" << endl; }
~S() { cout << "Destructor" << endl; }
};

S foo()
{
S s;
return s;
}

int main()
{
S s;

// Invoking with lvalue, will deduce X=S&, argument will be of type S&
MakeBox(s);

// Invoking with rvalue, will deduce X=S, argument will be of type S&&
MakeBox(foo());

return 0;
}

如果您有兴趣,这是 Scott Meyers 的一个非常好的类(class),他在其中解释了通用引用的行为方式:

Scott Meyers on universal references

P.S.:此答案已被编辑:我的原始答案建议使用 std::remove_reference<> ,但是 std::decay事实证明是一个更好的选择。感谢问题张贴者@Andrew Tomazos FathomlingCorps,他指出了这一点,并感谢@Mankarse,他首先在对原始问题的评论中提出了这一点。

关于c++ - 获取合适的存储值类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14089166/

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