gpt4 book ai didi

c++ - 如何在 C++ 中实现无参数仿函数及其返回值的有区别 union ?

转载 作者:太空狗 更新时间:2023-10-29 23:19:10 24 4
gpt4 key购买 nike

我知道我可以使用 boost::variant 并避免问这个问题。但是使用 boost::variant 涉及到很多丑陋的代码。尤其是来访者杂乱无章。所以,事不宜迟...

我编写了以下模板类来实现柯里化(Currying)函数的惰性求值。 (有关整个代码段,请参阅 my previous question。)

template <typename> class curry;

template <typename _Res>
class curry< _Res() >
{
public:
typedef std::function< _Res() > _Fun;
typedef _Res _Ret;

private:
_Fun _fun;

public:
explicit curry (_Fun fun)
: _fun(fun) { }

operator _Ret ()
{ return _fun(); }
};

所以我想更新它以包括内存。从概念上讲,它非常简单。首先,我必须更换:

private:
_Fun _fun;

public:
explicit curry (_Fun fun)
: _fun(fun) { }

与:

private:
bool _evaluated; // Already evaluated?
union
{
_Fun _fun; // No
_Res _res; // Yes
};

public:
explicit curry (_Fun fun)
: _evaluated(false), _fun(fun) { }

explicit curry (_Res res)
: _evaluated(true), _res(res) { }

但是还有两件事。首先,我必须更新 operator _Ret,这样,如果它执行惰性求值,那么结果实际上会被内存。其次,我必须添加一个析构函数,以便根据 _evaluated 的值,_fun_res 被销毁。这是我不太确定如何做事的地方。

首先,这是将 _fun 替换为 _res 的正确方法吗?如果没有,我应该怎么做?

operator _Ret ()
{
if (!_evaluated) {
_Fun fun = _fun;

// Critical two lines.
_fun.~_Fun();
_res._Res(fun());

_evaluated = true;
}
return _res;
}

其次,这是选择性销毁_fun_res 的正确方法吗?如果没有,我应该怎么做?

~curry ()
{
if (_evaluated)
_res.~_Res();
else
_fun.~_Fun();
}

最佳答案

您不能像其他评论者所说的那样使用 union ,但您可以使用 placement new .

这是一个使用 placement new 的可区分 union 示例:

请注意,您的平台上可能存在 A 和 B 类型的对齐限制,并且此代码不处理强制执行这些限制。

#include <iostream>
#include <cstring>

using namespace std;

struct foo {
foo(char val) : c(val) {
cout<<"Constructed foo with c: "<<c<<endl;
}

~foo() {
cout<<"Destructed foo with c: "<<c<<endl;
}
char c;
};

struct bar {
bar(int val) : i(val) {
cout<<"Constructed bar with i: "<<i<<endl;
}

~bar() {
cout<<"Destructed bar with i: "<<i<<endl;
}

int i;
};

template < size_t val1, size_t val2 >
struct static_sizet_max
{
static const size_t value
= ( val1 > val2) ? val1 : val2 ;
};

template <typename A, typename B>
struct unionType {
unionType(const A &a) : isA(true)
{
new(bytes) A(a);
}

unionType(const B &b) : isA(false)
{
new(bytes) B(b);
}

~unionType()
{
if(isA)
reinterpret_cast<A*>(bytes)->~A();
else
reinterpret_cast<B*>(bytes)->~B();
}

bool isA;
char bytes[static_sizet_max<sizeof(A), sizeof(B)>::value];
};

int main(int argc, char** argv)
{
typedef unionType<foo, bar> FooOrBar;

foo f('a');
bar b(-1);
FooOrBar uf(f);
FooOrBar ub(b);

cout<<"Size of foo: "<<sizeof(foo)<<endl;
cout<<"Size of bar: "<<sizeof(bar)<<endl;
cout<<"Size of bool: "<<sizeof(bool)<<endl;
cout<<"Size of union: "<<sizeof(FooOrBar)<<endl;
}

关于c++ - 如何在 C++ 中实现无参数仿函数及其返回值的有区别 union ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10436287/

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