接受模板类内部类的函数问题

时间:2011-08-24 16:26:06

标签: c++ templates

我在类模板中遇到内部类的问题。我有一个模板类(比如:Matrix<T>)和一个子类(比如:Matrix<T>::Row)。现在我想写一个操作子类实例的函数(比如:negate(Matrix<T>::Row &))。我试图用template<class T> negate(typename Matrix<T>::Row &)声明函数,但是当我尝试使用它时,编译器告诉我它找不到匹配。

这是一个抽象的例子:

template<class T>
class A
{
public:
    class B
    {
    };
};

template<class T>
void x(typename A<T>::B &)
{
}

int main()
{
    A<int>::B b;
    x(b); // doesn't work: Error: Could not find a match
          // for x<T>(A<int>::B) needed in main().
    x<int>(b); // works fine
}

为什么编译器在第一种情况下无法找到x?有没有办法修改它可以工作(没有明确指定类型int)?

(我也有类似的问题,其中x的格式为template<class T, class S> void x(typename A<T>::B &, const S &);,我真的不想在进行调用时强制显式命名所有类型。)

我用g ++ 4.4.3,g ++ 4.5.2和Sun Studio 5.9试过这个,都给出了相同的结果。非常感谢你提前做任何有用的事情!

3 个答案:

答案 0 :(得分:3)

编译器应如何推断出这一点?想象一下以下设置:

struct A { typedef int T; };
struct B { typedef int T; };

template <typename S> void foo(typename S::T);

现在当你说int x; foo(x);时,没有办法明确地与之匹配。

关键是你没有从给定的类模板中推断出模板参数,而只是一个任意的,独立的类型。该类型在另一个类中定义的事实与此无关。

答案 1 :(得分:2)

这是不可扣除的背景。这就是编译器无法推断出模板参数的原因。

想象一下,您可能有以下专门的A

template <>
struct A<SomeType>
{
    typedef std::map <double, double> B;
};

现在,这个专门化有一个名为B的嵌套类型,它是std::map<double,double>的typedef。

那么鉴于SomeTypeA<SomeType>::B,编译器将如何推导出类型std::map<double, double>

事实上,可以有许多这样的专业化,如下:

template <>
struct A<SomeOtherType>
{
    typedef std::map <double, double> B;
};

即使这种专业化也有B作为嵌套类型。

现在,如果我说A<T>::Bstd::map<double,double>,那么你能说出T是什么吗?是SomeType吗?还是SomeOtherType

答案 2 :(得分:1)

需要推导出模板函数x调用的类型T,并且模板参数推导仅在特定情况下允许:

http://publib.boulder.ibm.com/infocenter/compbgpl/v9v111/index.jsp?topic=/com.ibm.xlcpp9.bg.doc/language_ref/template_argument_deduction.htm

A<T>::B

似乎不是其中之一:/