C ++ с использованием шаблона функции в шаблоне класса

0
template <int C> class MyClass;

...     


template <int C>
double trans(MyClass<C> &a)
{
    //return some double 
}

//this is supposed to be function template
template <int C>
double func(MyClass<2> &a)
{
    //return some double
}

template <int C>
MyClass<C-1> func(MyClass<C> &a)
{
    MyClass<C-1> ret;
    return ret;
}

template <int C>
double otherFunc(MyClass<C> &a)
{
     double result;
     if(C == SOME_CONSTANT)
         result = func(a);
     else
         result = trans(func(a));

}

Что моя проблема, я хочу, чтобы проверить аргумент шаблона C в параметре otherFunc функции вызова шаблона func (вернуться дважды) вместо функции - члены шаблона класса func (возврата MyClass). Но каким-то образом компилятор пытается func который возвращает MyClass в

     if(C == SOME_CONSTANT)
         result = func(a);

эта часть, поэтому я получил ошибку компилятора (потому что double = MyClass не является жизнеспособным). Как мне исправить эту проблему?

  • 1
    otherFunc должен быть допустимым, чтобы компилировать значения C он создан, что включает в себя ветвь в операторе if / else которая никогда не может быть взята для этого значения C Другими словами, даже если SOME_CONSTANT равен 2 , он все равно проверит законность кода result = func(a) когда C не равен 2 приведет к ошибке преобразования, которую вы видите. Как исправить? - вы можете избежать if / else , имея общий шаблон otherFunc для C != 2 и специализацию для 2 . Хотя не очень понятно, чего вы на самом деле пытаетесь достичь ....
  • 0
    Я просто хочу, чтобы func себя немного иначе, чем другие, когда C == 2. Буду признателен, если вы укажете немного подробнее
Теги:
templates

2 ответа

0
Лучший ответ

Трудно уточнить в комментарии, поэтому я отправлю ответ. Чтобы повторить то, что я сказал в комментариях:

  • вы не можете иметь if/else в otherFunc, который не будет законным для компиляции для конкретного экземпляра MyClass,
  • вы можете использовать один и тот же подход к специализации шаблонов для создания альтернативного определения otherFunc для обработки MyClass<2> s.

Образец кода:

#include <iostream>

template <int C>
class MyClass
{ };

template <int C>
double trans(const MyClass<C> &a)
{
    return C + 700;
}

template <int C>
MyClass<C-1> func(MyClass<C> &a)
{
    MyClass<C-1> ret;
    return ret;
}


double func(MyClass<2>& a)
{
    return 200.0;
}

template <int C>
double otherFunc(MyClass<C> &a)
{
     return trans(func<C>(a));
}

template <>
double otherFunc<2>(MyClass<2>& a)
{
    return func(a);
}


int main()
{
    MyClass<2> a;
    std::cout << otherFunc(a) << '\n';

    MyClass<4> b;
    std::cout << otherFunc(b) << '\n';
}

Вывод:

200
703
  • 0
    Спасибо, я все еще пытаюсь изучить шаблон в c ++: / Я не мог понять идею специализации
  • 0
    @REALFREE: синтаксис требует некоторого привыкания ;-).
Показать ещё 2 комментария
0

Я думаю, причина в том, что:

 if(C == SOME_CONSTANT)
     result = func(a);
 else
     result = trans(func(a));

проверяется во время выполнения, тогда как специализация шаблонов и проверка типа выполняется во время компиляции. Эти 2 функции:

 template <int C>
 double func(MyClass<2> &a)
 {
     //return some double
 }

 template <int C>
 MyClass<C-1> func(MyClass<C> &a)
 {
     MyClass<C-1> ret;
     return ret;
 }

имеют почти одинаковые подписи - единственное различие заключается в том, что для C==2 используется один возвращаемый double, в противном случае используется тот, который возвращает MyClass<2>. Итак, что вы получаете:

 // for C==2
 if(C == SOME_CONSTANT)
     result = func<2>(a); // returns double - just like you wanted
 else
     result = trans<2>(func<2>(a)); // pass double into trans<?>(MyClass<?>), so the parameter cannot be resolved unless you specified some implicit constructor/explicit conversion operator 

 // for e.g. C==3
 if(C == SOME_CONSTANT)
     result = func<3>(a); // returns MyClass<2> while result is double
 else
     result = trans<2>(func<3>(a)); // pass MyClass<2> into trans<?>(MyClass<>) - like you wanted

поэтому в основном ваш код имеет недопустимый тип для специализаций в первом или втором случае. Вместо этого вы можете сделать что-то вроде этого:

 template <>
 MyClass<2> func<2>(MyClass<2> &a)
 {
     return a;
 }

 template <int C>
 MyClass<C-1> func(MyClass<C> &a)
 {
     return MyClass<C-1>;
 }

для сохранения типа шаблонов, а затем:

if(C == SOME_CONSTANT)
   result = trans(a);
else
   result = trans(func(a));

Это просто пример того, как справиться с этим. Все должно быть проще, если вы избегаете возиться с другим возвратом, напечатанным для разных специализированных шаблонов.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню