基于以下模板化结构,用作像素访问器。
template<class T, std::size_t N>
struct PixelAccessor
{
T ch[N];
};
using pxUChar_C1 = PixelAccessor<unsigned char, 1>;
using pxUChar_C3 = PixelAccessor<unsigned char, 3>;
using pxUChar_C4 = PixelAccessor<unsigned char, 4>;
using pxFloat_C1 = PixelAccessor<float, 1>;
using pxFloat_C3 = PixelAccessor<float, 3>;
using pxFloat_C4 = PixelAccessor<float, 4>;
// etc. for all other types (int, short, ushort, ...)
我做了以下功能,仅适用于3个通道的uchar和float像素。
template<typename T, typename = typename std::enable_if<std::is_same<T, pxUChar_C3>::value || std::is_same<T, pxFloat_C3>::value>::type>
bool function(Image img) {
// where getData is uchar*, and cast to T** allow 2D accessing
auto imgPtr = (T**)img->getData();
}
是否可以执行以下操作或类似的操作?我想启用所有3通道像素,那是什么类型?
template<typename T, typename = typename std::enable_if<std::is_base_of< PixelAcessor<std::any, 3>,T>::value>::type>
我想拥有一个C ++ 11解决方案,但是如果需要更新的编译器,我欢迎解决方案并查看我的工作。
答案 0 :(得分:5)
要使函数采用PixelAccessor
为N
的任何3
,则不需要enable_if
和SFINAE。只是使用
template<typename T>
return_type function_name(PixelAccessor<T, 3> parameter_name)
{
// stuff
}
将为您提供一个函数,该函数采用任意类型的PixelAccessor
,大小为3。
答案 1 :(得分:1)
您可以使用自定义渠道提取元功能:
template<typename> struct GetPixelAccessorChannel
{ static constexpr std::size_t value = 0; };
template<typename T, std::size_t N> struct GetPixelAccessorChannel<PixelAccessor<T, N>>
{ static constexpr std::size_t value = N; };
现在,只需在enable_if
中测试适当的条件即可。
template<typename T, typename = typename std::enable_if<GetPixelAccessorChannel<T>::value == 3>::type>
bool function();
顺便说一句,我会代您考虑(T**)img->getData()
。对我来说,需要这样的演员阵容非常可疑。
答案 2 :(得分:0)
正如评论中指出的那样,模板中无法使用通配符,例如std::any
。
但是在讨论之后,像我问的那样使用模板有点愚蠢,因为我想始终将T本身用作PixelAccessor,因此可以以不同的方式使用它,例如我仅为PixelAccessor模板T本身。
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
bool function(Image img) {
// Sanity check
if(img->getNbChannels() != 3) return false;
// where getData is uchar*, and cast to T** allow 2D accessing
auto imgPtr = (PixelAccessor<T, 3>**)img->getData();
}