C++ 如果仅使用模板,则启用模板功能

C++ 如果仅使用模板,则启用模板功能,c++,c++11,templates,C++,C++11,Templates,基于以下模板结构,用作像素访问器 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<

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

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, ...)
我使以下函数仅适用于uchar和浮动像素,它们是3个通道

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解决方案,但如果需要一个更新的编译器,我会打开这个解决方案,看看我该怎么做。

要获得函数以获取N为3的任何像素访问器,则不需要启用if和SFINAE。只是使用

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

将为您提供一个函数,该函数接受任何类型的像素访问器,大小为3。

若要获取函数以接受N为3的任何像素访问器,则不需要启用if和SFINAE。只是使用

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

将为您提供一个函数,该函数接受任何类型的像素访问器,大小为3。

您可以使用自定义通道提取元函数:

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; }; 

顺便说一句,我会重新考虑用T**img->getData代替你。对我来说,需要这样的演员阵容看起来很可疑。

您可以使用自定义频道提取元函数:

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; }; 

顺便说一句,我会重新考虑用T**img->getData代替你。对我来说,需要这样的强制转换看起来很可疑。

正如评论中所指出的,在模板中不可能使用通配符,如std::any

但是经过讨论后,我问过的模板的使用有点愚蠢,因为我想总是将T用作像素访问器本身,所以可以使用不同的方法,比如我只为像素访问器本身模板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();
}

正如注释中指出的,在模板中不可能使用通配符,如std::any

但是经过讨论后,我问过的模板的使用有点愚蠢,因为我想总是将T用作像素访问器本身,所以可以使用不同的方法,比如我只为像素访问器本身模板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();
}

这是行不通的,std::any不是模板推导的通配符。但是你可以尝试给PixelAccessor一个简单的基类型,这样所有的PixelAccessor都可以用is_base_进行测试。类似于PixelAccessorBase的东西,因为你想允许任何类型的PixelAccessor,只要它有一些期望值N。我知道它不起作用。我想知道如何用一些可以替代std::any的东西。我把std::any放在这里是为了说明我试图用诸如any之类的明显术语做什么。函数如何使用T?或者像素转换器。@Vuwox没有这样的通配符占位符。编辑:继承方法可能是解决您试图做的事情的最简单的解决方案。你也可以试着写下你自己的类型特征。@Fureeish-这不是内森所建议的。Nathan的答案取决于使用像素访问器的功能,而不是OP的功能。我怀疑OP的意思是在演员阵容中简单地使用PixelAccessor**这是行不通的,std::any不是模板演绎的通配符。但是你可以尝试给PixelAccessor一个简单的基类型,这样所有的PixelAccessor都可以用is_base_进行测试。类似于PixelAccessorBase的东西,因为你想允许任何类型的PixelAccessor,只要它有一些期望值N。我知道它不起作用。我想知道如何用一些可以替代std::any的东西。我把std::any放在这里是为了说明我试图用诸如any之类的明显术语做什么。函数如何使用T?或者像素转换器。@Vuwox没有这样的通配符占位符。编辑:继承方法可能是解决您试图做的事情的最简单的解决方案。你也可以试着写下你自己的类型特征。@Fureeish-这不是内森所建议的。Nathan的答案取决于使用像素访问器的功能,而不是OP的功能。我怀疑OP的意思是在cast中简单地执行PixelAccessor**操作。该代码与以前的开发人员的代码类似。它也避免处理行间距、通道数等,以便cast能够更快地访问。@Vuwox-叹气。似乎每个组织中都有以前的开发人员编写类似的代码。以前的开发人员编写了类似的代码。避免处理行间距、通道数等也很重要,这样才能使强制转换能够更快地访问。@Vuwox-Sigh。似乎每个组织中都有以前的开发人员编写类似的代码。