enable_if模板参数是 lambda(具有特定签名)

enable_if template param is lambda (with particular signature)

本文关键字:lambda if 参数 enable      更新时间:2023-10-16

我有这个:

template<typename T>
class Image {
Image(int w, int h, T defaultVal){
for(int i=0; i<h; i++)
for(int j=0; j<w; j++)
pixel(j, i) = defaultVal;
}
template<typename F>
Image(int w, int h, F initializer){
for(int i=0; i<h; i++)
for(int j=0; j<w; j++)
pixel(j, i) = initializer(j, i);
}
// ...
};

我的目的是能够实例化这样的Image

Image<int> img0(w, h, 0); // image of zeroes
Image<int> imgF(w, h, [](int j, int i){ // checkerboard image
return (j/10+i/10) % 2;
});

但是,当然,第二个构造函数签名将与第一个构造函数签名冲突。为了解决此冲突,我想限制第二个构造函数的可能模板实例化。

我不想让它太复杂。你可以帮我吗?我的尝试:

template<typename F, typename = std::enable_if_t< // what now? how to check that F is callable (and if simple to check, with appropriate signature)

您正在寻找std::is_invocable

template<typename F, typename = std::enable_if_t<
std::is_invocable<F&, int, int>>

F&因为您将其作为左值调用,然后它只是参数类型的列表。


以上需要C++17。它可以在 C++14 上实现,但在您的情况下,我们也可以采用更简单的方法,只需执行以下操作:

template <typename F, typename = decltype(std::declval<F&>()(1, 1))>

F&的原因与上面相同,其余的表达式更熟悉。由于我们用int调用,我们不关心INVOKE允许的其他事情(例如指向成员的指针(。