Специализация шаблона функции с аргументами const ref - PullRequest
1 голос
/ 13 февраля 2020

Следующий код прекрасно компилируется .

#include <iostream>

struct rgb8{
    uint8_t r() const {return 0;};
};


template<typename L, typename P>
L pixelToLevel(P p) {
    return static_cast<L>(p);
}

template<>
uint8_t pixelToLevel<uint8_t, rgb8>(rgb8 p) {  //       <---------- line X
    return pixelToLevel<uint8_t, uint8_t>(p.r());
}


int main()
{
  pixelToLevel<uint8_t>(rgb8());
  return 0;
}

Но если в строке XI изменить rgb8 p на const rgb8& p, он не скомпилируется.

( Точная сгенерированная ошибка компилятора зависит от того, был ли явный аргумент шаблона rgb8 также изменен на const rgb8&.)

Как мне заставить его скомпилироваться, если я хочу передать p по ссылке, а не чем по значению в строке X?

Ответы [ 2 ]

1 голос
/ 13 февраля 2020

Альтернативное решение для @ songyuanyao было бы

template<typename L, typename P>
L pixelToLevel(const P& p) {
    return static_cast<L>(p);
}
1 голос
/ 13 февраля 2020

Вам необходимо изменить параметр шаблона в объявлении специализации и аргумент шаблона при его вызове. В противном случае будет вызван основной шаблон. Например,

template<>
uint8_t pixelToLevel<uint8_t, const rgb8&>(const rgb8& p) {  //       <---------- line X
    return pixelToLevel<uint8_t, uint8_t>(p.r());
}

, затем

pixelToLevel<uint8_t, const rgb8&>(rgb8());

LIVE


РЕДАКТИРОВАТЬ

Дано pixelToLevel<uint8_t>(rgb8());, вывод аргумента шаблона выполняется с первичным шаблоном, а P выводится как rgb8 (он не будет выводиться как const rgb8& с объявлением параметра текущего первичного шаблона), тогда версия специализации вызываться не будет .

Вы можете применить перегрузку вместо специализации шаблона. например,

template<typename L, typename P>
L pixelToLevel(P p) {
    return static_cast<L>(p);
}

template<typename L>
L pixelToLevel(const rgb8& p) {  //       <---------- line X
    return pixelToLevel<L, uint8_t>(p.r());
}

Тогда pixelToLevel<uint8_t>(rgb8()); выберет 2-ю перегрузку.

LIVE

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...