我有一个模板化的类,我在其中定义了引用该模板化类的自由函数。这些自由函数也可以在不同的参数上进行模板化。
从课外我可以调用免费功能。但是,我无法找到一个自由函数的正确语法来调用另一个函数。
快速举例:
template<typename T> class Foo {
template<typename S>
friend S f(const Foo &) { return S(); }
template<typename S>
friend S g(const Foo &s) {
return f(s); // See below, when instantiated, yields 'no matching function for call to f(const Foo &)'
}
};
float test1() {
Foo<int> o;
return f<float>(o); // Compiles
}
float test2() {
Foo<int> o;
return g<float>(o); // Fails to compile as line above errors
}
(c.f。this link)
似乎在g()中调用f(s)时,最外面的模板已经丢失。如何在f调用中重新指定T?我已经检查了GCC4.7,4.8,clang 3.2都有相同的错误。
答案 0 :(得分:6)
当您致电f(s)
时,您需要指定模板参数S
,因为无法从参数s
中推断出它。
但是如果你把它更改为f<S>(s)
(假设你打算使用相同的模板参数S
调用它,而g
被调用)那么你就会禁止ADL,这是唯一的方法在类范围定义的友元函数可以通过ADL找到。因此,您需要向全局命名空间添加f
声明,以便g
中的调用可以找到它。
为了使其工作,您需要在Foo
template<typename T> class Foo;
template<typename S, typename T>
S f(const Foo<T> &);
template<typename S, typename T>
S g(const Foo<T> &);
并将g
中的来电更改为f<S>(s)
或其他内容,例如f<x>(s)