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 не является жизнеспособным). Как мне исправить эту проблему?
Трудно уточнить в комментарии, поэтому я отправлю ответ. Чтобы повторить то, что я сказал в комментариях:
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
Я думаю, причина в том, что:
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));
Это просто пример того, как справиться с этим. Все должно быть проще, если вы избегаете возиться с другим возвратом, напечатанным для разных специализированных шаблонов.
otherFunc
должен быть допустимым, чтобы компилировать значенияC
он создан, что включает в себя ветвь в оператореif
/else
которая никогда не может быть взята для этого значенияC
Другими словами, даже еслиSOME_CONSTANT
равен2
, он все равно проверит законность кодаresult = func(a)
когдаC
не равен2
приведет к ошибке преобразования, которую вы видите. Как исправить? - вы можете избежатьif
/else
, имея общий шаблонotherFunc
дляC != 2
и специализацию для2
. Хотя не очень понятно, чего вы на самом деле пытаетесь достичь ....func
себя немного иначе, чем другие, когда C == 2. Буду признателен, если вы укажете немного подробнее