我从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);
}
答案 0 :(得分:5)
这是因为std :: plus不是函数。
您的函数plus在全局命名空间中,因此您需要执行
Struct result = ::plus(x, y);
它尝试使用std :: plus的原因是因为你没有明确加上你想要的版本,所以编译器使用Koenig lookup通过其参数找到了加号。
答案 1 :(得分:0)
尝试明确指定名称空间加上()
Struct result = ::plus(x, y);
这有助于gcc,它不会让你把你的plus()放到不同的命名空间。
Loki Astari告诉其余人
答案 2 :(得分:0)
如果将函数放在不同的命名空间中,则不会出现此错误。这就是命名空间的用途 - 您可以在不同的命名空间中使用相同的符号/签名,而不会导致冲突。