Возьмем простейший шаблон функции с нетипизированными параметрами:
template<int A, int B > int ss(int a, int b)
{
return A*a + B*b;
}
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print(ss<2,2>(2,3));
}
Вопрос вот такой - как задать в качестве параметра шаблона третий аргумент, являющийся производным от первых двух, что-то типа
template<int A, int B, int (A+B) > int ss(int a, int b)
Проще наверно будет обьяснить, зачем это надо…
Вот у меня есть функция, код которой зависит от параметров A B. Для всех возможных A B код один, а для случая когда A + B равно 40 - код совершенно другой. Как мне запрограммировать специализацию шаблона для этого “особого” варианта?
ЗЫ шаблон и объявление функции на одной строке - это не моя прихоть, это Ардуино ИДЕ иначе не понимает.
Чтобы понять как отвечать и не слишком долго толочь воду в ступе, скажите, Вы в принципе умеете специализировать шаблон в зависимости от значения параметра? Например, пусть в шаблоне всего один параметр, Вы можете сгенерировать один код для случая, когда он равен 40 и другой код для всех остальных случаев?
И заодно, Вас устроят примеры в Atmel Studio или обязательно в IDE?
Так, я понял что поступил некрасиво, выложив пример функции, когда меня интересует классс. Функция не допускает частичной специализации, поэтому тут и обсуждать нечего.
Исправляюсь, вот шаблонный класс с примером частичной специализации:
template<int A, int B >
class AA
{
public:
int foo() {return A + B;}
};
template<int A >
class AA<A, 40>
{
public:
int foo() {return A + 22;}
};
AA<2,3> aa;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print(aa.foo());
}
Пипец! А я ВСЁ это время писал для Вас пример “обертки” функции в класс (функтора), чтобы обойти это ограничение и воспользоваться частичной специализацией
Значит, так, давайте я Вам покажу готовый, работающий функтор (это обёртка класса над функцией, когда в классе определён оператор вызова функции). Думаю, Вы поймёте подход и дальше сделаете для любого класса по образу и подобию сами. Если нет, то пишите в чём проблема, но я сейчас исчезаю и вернусь после хоккея, так что скоро ответов не ждите
Работающий пример с функтором
#define printVar(x) do { Serial.print(#x "="); Serial.print(x); Serial.print("; "); } while (false)
#define printVarLn(x) do { Serial.print(#x "="); Serial.println(x); } while (false)
template <int A, int B, int C = A + B> struct Functor { int operator()(int a, int b) {return A*a + B*b; } };
template <int A, int B> struct Functor<A, B, 40> { int operator()(int a, int b) {return a + b; } };
void setup(void) {
Serial.begin(9600);
Serial.println("Let's go!");
Functor<20,21> ss1;
Functor<19,21> ss2; // равно 40
int s1 = ss1(2,3); // Должно быть 103
int s2 = ss2(2,3); // Должно быть 5
printVarLn(s1);
printVarLn(s2);
}
void loop(void) {}
Кстати, посмотрите как бы красиво и просто всё решалось в
С++17 с if constexpr
template<int A, int B> int ss(int a, int b) {
if constexpr (A+B == 40) {
return a + b;
} else {
return A*a + B*b;
}
}
template<int A, int B, int C = A + B >
class AA
{
public:
int foo() {return A + B;}
};
template<int A, int B >
class AA< A, B, 40>
{
public:
int foo() {return A + 22;}
};
AA<2,3> aa;
AA<2,38> bb;
так просто???
Какого же фига ни в одном пособии по шаблоном этого нет?
я не знаю, что может быть проще тем третий параметр как int C = A + B… и работает в любом компиляторе
template<int A, int B, int S> class _first
{
public:
_first () {
Serial.printf("First example for %d %d %d\n", A, B, S);
}
};
template<int A, int B> class _first<A,B, 50>
{
public:
_first () {
Serial.printf("First example SPECIAL!!! %d %d\n", A, B);
}
};
template<int A, int B> class First {
_first<A,B,A+B> _firstExample;
};
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
First<10,11> e1;
First<24,26> e2;
}
void loop() {
// put your main code here, to run repeatedly:
delay(10); // this speeds up the simulation
}
Вот вывод вокви:
Hello, ESP32!
First example for 10 11 21
First example SPECIAL!!! 24 26
это как-бы подразумевается. В шаблоне ты используешь типовое определение переменной, в нем может быть инициализатор. далее - по тексту стандарта. Но да, изучение С++ творческое занятие. Угадывать многое нужно