我在类模板中遇到内部类的问题。我有一个模板类(比如: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试过这个,都给出了相同的结果。非常感谢你提前做任何有用的事情!
答案 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。
那么鉴于SomeType
是A<SomeType>::B
,编译器将如何推导出类型std::map<double, double>
?
事实上,可以有许多这样的专业化,如下:
template <>
struct A<SomeOtherType>
{
typedef std::map <double, double> B;
};
即使这种专业化也有B
作为嵌套类型。
现在,如果我说A<T>::B
是std::map<double,double>
,那么你能说出T
是什么吗?是SomeType
吗?还是SomeOtherType
?
答案 2 :(得分:1)
需要推导出模板函数x调用的类型T,并且模板参数推导仅在特定情况下允许:
A<T>::B
似乎不是其中之一:/