我正在用C++测试一个 Package 器对象,这是我的基本代码:
template <class res_type, class finisher_type, finisher_type finisher>
struct wrapper
{
wrapper(res_type r, finisher_type) noexcept
{
item = r;
}
wrapper(res_type r) noexcept
{
item = r;
}
~wrapper() noexcept
{
finisher(item);
}
private:
res_type item;
};
template <class func, func lambda = func()>
explicit wrapper(int, func)->wrapper<int, func, lambda>;
void test()
{
int x = 0, y = 0;
wrapper file{ x, [](int h) {if (h != -1 && h) close_resource(h); } };
// void some_closer_function(int) {...}
wrapper proc{ y, some_closer_function };
}
我面临两个问题。首先,在lambda捕获子句中放入任何内容都会使编译器抱怨'wrapper<int,func,lambda> wrapper(int,func)': could not deduce template argument for 'lambda'
。这是因为带有捕获的lambda不能使用+
转换为函数指针吗?
第二,使用some_closer_function
的行编译,但由于演绎指南中的func lambda = func()
,lambda
是nullptr
。我认为这是因为演绎指南中的func
是函数指针,而不是函数类型本身。有没有办法强制它成为函数本身而不是函数指针,而不显式输入decltype(some_closer_function)
?
编辑3/25/2023
我创建了一个派生类来保存一个lambda,但这次是一个捕获类,因为我之前的代码可以保存一个无捕获的lambda。新的派生类通过保存一个指向lambda的指针,然后通过该指针调用它来实现这一点。
template <class res_type, class finisher_type, finisher_type finisher = finisher_type()>
struct wrapper
{
wrapper(res_type r, finisher_type) noexcept
{
item = r;
}
wrapper(res_type r) noexcept
{
item = r;
}
~wrapper() noexcept
{
if constexpr (!std::is_same_v<finisher_type, std::nullptr_t>)
finisher(item);
}
protected:
res_type item;
};
template <class res_type, class lambda_type>
struct custom_wrapper : wrapper<res_type, std::nullptr_t>
{
custom_wrapper(res_type item, lambda_type const& lambda) : base(item)
{
this->lambda = λ
}
~custom_wrapper()
{
lambda->operator()(base::item);
}
private:
using base = wrapper<res_type, std::nullptr_t>;
const lambda_type* lambda;
};
void test()
{
int x, y;
custom_wrapper wrapper{ 234, [&](int) {} };
return;
}
虽然这确实使一切工作,但这是未定义的行为吗?我问这个问题是因为我相信捕获lambda是包含捕获的class
。在这种情况下,lambda对象是临时对象吗?就像在custom_wrapper wrapper{ 234, [&](int) {} };
行中一样,并在custom_wrapper
完成创建时被销毁?当custom_wrapper
被销毁时,它最终会调用一个被销毁的lambda吗
1条答案
按热度按时间6ojccjat1#
函数形参 values 不参与模板实参推导。即使是类模板实参推导。非类型模板形参的模板形参不能推导。该形参的类型可以推导(
template<auto value>
是一个东西),但不能将其初始化为对象。因此,如果要使用非类型模板参数,则必须由模板参数列表显式提供。
算是吧
如果你将一个值绑定到某个其他类的NTTP中,那么你可以将该类的一个示例作为参数传递,并让模板参数演绎来处理它。例如:
你可以在这里做基本相同的事情,只是使用一个对NTTP有效的类用途:
然后,您可以在类的构造函数中使用它,并使用适当的演绎指南来整理细节:
当然,这意味着任何可调用对象都必须捆绑到
compile_constant<callable>{}
表达式中,但这就是试图将编译时常量偷偷带入函数参数的代价。Here's a working example.