gpt4 book ai didi

c++ - 处理模板中的 void 类型

转载 作者:可可西里 更新时间:2023-11-01 15:20:18 27 4
gpt4 key购买 nike

我有一个模板函数调用另一个函数并存储它的返回值,然后在返回值之前做一些工作。我想扩展它以处理 T = void,并且想知道特化是否是我唯一的选择。

template<typename T>
T Foo( T(*Func)() )
{
// do something first (e.g. some setup)
T result = Func();
// do something after (e.g. some tear down)
return result;
}

// Is this specialization the only option?
template<>
void Foo<void>( void(*Func)() )
{
// do something first (e.g. some setup)
Func();
// do something after (e.g. some tear down)
return;
}

void Bar() {}
int BarInt() { return 1; }

int main()
{
Foo<int>(&BarInt);
Foo<void>(&Bar);
}

或者可以修改 Foo 的常规版本以处理 void 类型并且在那种情况下基本上什么也不做?我当时在想,也许我的本地结果可以包装在一个可以处理 void 的类型中,但也可以将分配视为交易破坏者。

最佳答案

鉴于您的操作不依赖于函数的结果,您无需专门化即可完成。返回 void 的函数是可以的返回 void 类型的表达式.所以 return部分不是麻烦的部分,但是您需要想出一种方法来进行前后操作。构造函数和析构函数将在这方面帮助您:

struct do_something_helper
{
do_something_helper()
{
// do something first (e.g. take a lock)
}
~do_something_helper()
{
// do something after (e.g. release a lock)
}
};

然后你可以这样写你的函数:

template<typename T>
T Foo( T(*Func)() )
{
do_something_helper _dummy_helper; // constructor called here

return Func();
// destructor called here
}

对于您评论的使用 lambda 的更通用的解决方案,它可能如下所示:

template< typename Pre, typename Post >
struct scope_guard
{
scope_guard( Pre&& pre, Post&& post )
: _post( std::forward< Post >( post ) )
{
pre();
}
~scope_guard()
{
_post();
}

Post _post;
};

template< typename Pre, typename Post >
scope_guard< Pre, Post > make_scope_guard( Pre&& pre, Post&& post )
{
return scope_guard< Pre, Post >( std::forward< Pre >( pre ), std::forward< Post >( post ) );
}

template<typename T>
T Foo( T(*Func)() )
{
auto do_something_helper =
make_scope_guard(
[](){ /* do something first (e.g. take a lock) */ },
[](){ /* do something after (e.g. release a lock) */ }
);

return Func();
}

使用 std::function< void() >类型删除 版本会更容易编写和使用,但效率会很低。

关于c++ - 处理模板中的 void 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14205761/

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