如何摆脱手动类模板参数规范
How to get rid of the manual class template parameter specification
还有比这更通用的方法来编写Finalizer
类吗?
#include <functional>
#include <iostream>
template <typename T>
class Finalizer
{
public:
Finalizer(const std::function<T>& f) : _f(f) {}
~Finalizer()
{
_f();
}
private:
std::function<T> _f;
};
int main()
{
Finalizer<void()> finalizer([]() { std::cout << "str" << std::endl; });
}
我想摆脱手动类模板参数规范,以便能够编写这样的代码:
Finalizer finalizer([]() { std::cout << "str" << std::endl; });
可能吗?
在C++类型推导仅适用于函数模板,不适用于类模板。您需要一个make_finalizer
函数来执行模板参数推导。
此外,您根本不需要使用std::function
,无需支付运行时成本,除非您确实希望将其类型擦除。
template <typename F>
class Finalizer
{
public:
Finalizer(const F & c) : f_(c) {}
Finalizer(F && c) : f_(std::move(c)) {}
Finalizer(const Finalizer &) = delete;
Finalizer(Finalizer && other) :
valid_(other.valid),
f_(std::move(other.f_))
{
other.valid_ = false;
}
Finalizer& operator=(const Finalizer &) = delete;
Finalizer& operator=(Finalizer && other)
{
Finalizer tmp(std::move(other));
swap(tmp);
return *this;
}
~Finalizer()
{
if ( valid_ )
f_();
}
void swap(Finalizer & other) noexcept
{
using std::swap;
swap(other.valid_, valid_);
swap(other.f_, f_);
}
private:
bool valid_ = true;
F f_;
};
template<class F>
Finalizer< std::remove_reference_t<F> > at_scope_exit(F && x)
{
return Finalizer< std::remove_reference_t<F> >(std::forward<F>(x));
}
并将其与自动一起使用:
auto x = at_scope_exit([]() { std::cout << "Hello world" << std::endl; });
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 摆脱可变参数模板递归基本情况下不必要的类
- 检查布尔模板参数时摆脱"conditional expression is constant"警告的方法?
- 如何摆脱手动类模板参数规范
- "return-by-reference"或"pass-by-reference"参数何时与constexpr兼容?