Функция шаблона включена, если только с шаблоном - PullRequest
1 голос
/ 11 марта 2019

На основе следующей шаблонной структуры, используемой в качестве средства доступа к пикселям.

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 и float, которые являются 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, но если есть необходимость в более новом компиляторе, я открытк решению и посмотреть, что я делаю.

Ответы [ 3 ]

5 голосов
/ 11 марта 2019

Чтобы получить функцию для любого PixelAccessor, где N равно 3, вам не нужны enable_if и SFINAE.Простое использование

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

даст вам функцию, которая принимает PixelAccessor любого типа и имеет размер 3.

1 голос
/ 11 марта 2019

Вы можете использовать собственную мета-функцию извлечения канала:

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() вместо вас.Мне нужен такой бросок, выглядит очень подозрительно.

0 голосов
/ 11 марта 2019

Как указано в комментариях, использование шаблона, такого как std::any, невозможно в шаблоне.

Но после обсуждения использование шаблона, как я и просил, было немного глупо, так как яЯ хочу всегда использовать T в качестве самого PixelAccessor, чтобы можно было использовать его по-другому, например, я только шаблонирую T для самого PixelAccessor.

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...