4

我从 g++ 收到一个奇怪的编译器错误。

std::plus is not a function为以下代码显示“”,即使我没有包括<functional>并且我没有使用std发生错误的位置。

这是代码:

#include <iostream>

template<class T1, class T2, class T3>
struct MyStruct {
  T1 t1; T2 t2; T3 t3;
  MyStruct() {}
  MyStruct(T1 const& t1_, T2 const& t2_, T3 const& t3_)
    : t1(t1_), t2(t2_), t3(t3_) {}
};

template<class T1, class T2, class T3>
MyStruct<T1, T2, T3> plus(MyStruct<T1, T2, T3> const& x,
              MyStruct<T1, T2, T3> const& y) {
  // ...
}

int main() {
  typedef MyStruct<int, double, std::string> Struct;
  Struct x(2, 5.6, "bar");
  Struct y(6, 4.1, "foo");
  Struct result = plus(x, y);
}

这是完整的错误(稍微重新格式化):

/usr/include/c++/4.2.1/bits/stl_function.h: In function 'int main()':
/usr/include/c++/4.2.1/bits/stl_function.h:134:
    error: 'template<class _Tp> struct std::plus' is not a function,
plus3.cc:13: error:
   conflict with 'template<class T1, class T2, class T3> 
     MyStruct<T1, T2, T3> plus(const MyStruct<T1, T2, T3>&, 
       const MyStruct<T1, T2, T3>&)'
plus3.cc:21: error:   in call to 'plus'

有谁知道这是为什么以及如何避免错误?我真的很想调用这个函数plus

plus当我的函数没有 3 个模板参数时,该错误不会发生,这在查看以下定义后是有道理的std::plus

  template <class _Tp>
    struct plus : public binary_function<_Tp, _Tp, _Tp>

但这仍然很奇怪,因为std::plus那时甚至不应该知道。

更新:

作为对一些答案的回应,我将粘贴稍作修改的代码,这也会给出错误。我的plus函数在namespace foo这里,它是从同一个命名空间调用的,所以应该没有必要使用它来限定它foo::

#include <string>

namespace foo {

template<class T1, class T2, class T3>
struct MyStruct {
  T1 t1; T2 t2; T3 t3;
  MyStruct() {}
  MyStruct(T1 const& t1_, T2 const& t2_, T3 const& t3_)
      : t1(t1_), t2(t2_), t3(t3_) {}
};

template<class T1, class T2, class T3>
MyStruct<T1, T2, T3> plus(MyStruct<T1, T2, T3> const& x,
                          MyStruct<T1, T2, T3> const& y) {
  // ...                                                                                                                        
}

template<class T1, class T2, class T3>
MyStruct<T1, T2, T3> bar(MyStruct<T1, T2, T3> const& x,
                         MyStruct<T1, T2, T3> const& y) {
  return plus(x, y);
}

} // end foo                                                                                                                    

int main() {
  typedef foo::MyStruct<int, double, std::string> Struct;
  Struct x(2, 5.6, "bar");
  Struct y(6, 4.1, "foo");
  Struct result = foo::bar(x, y);
}
4

3 回答 3

5

这是因为 std::plus 不是函数。

您的函数 plus 位于全局命名空间中,因此您需要这样做

Struct result = ::plus(x, y);

它尝试使用 std::plus 的原因是因为您没有明确说明您想要的 plus 版本,因此编译器使用Koenig 查找,该查找通过其参数找到 plus。

于 2012-05-22T20:43:56.883 回答
0

尝试为您明确指定命名空间 plus()

Struct result = ::plus(x, y);

这对 gcc 有帮助,并且不会让您将 plus() 放入不同的名称空间。

Loki Astari 告诉其他人

于 2012-05-22T20:37:55.947 回答
0

如果将函数放在不同的命名空间中,则不会出现此错误。这就是命名空间的用途——您可以在不同的命名空间中拥有相同的符号/签名而不会导致冲突。

于 2012-05-22T20:40:46.227 回答