如何在C ++中引用双重模板化的自由函数

时间:2013-05-21 15:25:43

标签: c++ templates

我有一个模板化的类,我在其中定义了引用该模板化类的自由函数。这些自由函数也可以在不同的参数上进行模板化。

从课外我可以调用免费功能。但是,我无法找到一个自由函数的正确语法来调用另一个函数。

快速举例:

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都有相同的错误。

1 个答案:

答案 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)