1

基于以下模板化结构,用作像素访问器。

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 解决方案,但如果需要更新的编译器,我愿意接受解决方案,看看我做了什么。

4

3 回答 3

5

要使功能可以在任何PixelAccessor地方使用N3那么您不需要enable_ifSFINAE。只是使用

template<typename T>
return_type function_name(PixelAccessor<T, 3> parameter_name)
{
    // stuff
}

将为您提供一个采用PixelAccessor任何类型且大小为 3 的函数。

于 2019-03-11T15:04:33.947 回答
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()代替你重新考虑。需要这样的演员阵容对我来说很可疑。

于 2019-03-11T15:06:53.940 回答
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();
}
于 2019-03-11T15:19:40.450 回答