C ++使用类模板中的函数模板

时间:2014-01-29 02:30:00

标签: c++ templates

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));

}

我的问题是我想检查参数otherFunc中的模板参数C调用函数模板func(返回double)而不是类模板func的成员函数(返回MyClass)。但不知何故,编译器尝试func返回

中的MyClass
     if(C == SOME_CONSTANT)
         result = func(a);

这部分因此我得到了编译器错误(因为double = MyClass不可行)。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我猜原因是:

 if(C == SOME_CONSTANT)
     result = func(a);
 else
     result = trans(func(a));
在运行时检查

,同时在编译期间完成模板特化和类型检查。这两个功能:

 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));

这只是一个如何处理它的例子。如果您避免弄乱为不同的模板专业化输入的不同返回值,事情应该会更容易。

答案 1 :(得分:0)

很难在评论中详细说明,所以我会发布一个答案。回顾我在评论中所说的话:

  • if中的else / otherFunc无法为特定MyClass实例化编译合法,
  • 可以 使用相同的模板专精化方法来创建替代otherFunc定义来处理MyClass<2>

示例代码:

#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