C++ 重载 Copysign 运算符冲突或不明确
C++ Overloaded Copysign Operator either conflicting or ambiguous
我正在尝试解决与现在看来已过时的开源游戏相关的问题。当我想玩它时,我正在尝试构建它并可能向其中添加一些东西。
不幸的是,我遇到了一些问题,我的 C++ 技能确实欠缺。
In file included from /home/talrose/projects/Vegastrike/engine/src/cmd/../gfx/camera.h:24:0,
from /home/talrose/projects/Vegastrike/engine/src/cmd/beam_generic.cpp:8:
/home/talrose/projects/Vegastrike/engine/src/physics.h:30:34: error: ‘float copysign(float, float)’ conflicts with a previous declaration
float copysign( float x, float y );
^
In file included from /usr/include/c++/6/math.h:36:0,
from /projects/Vegastrike/engine/src/vs_math.h:27,
from /projects/Vegastrike/engine/src/vegastrike.h:36,
from /projects/Vegastrike/engine/src/cmd/beam_generic.cpp:1:
/usr/include/c++/6/cmath:1288:3: note: previous declaration ‘constexpr float std::copysign(float, float)’
copysign(float __x, float __y)
^~~~~~~~
CMakeFiles/engine_com.dir/build.make:614: recipe for target 'CMakeFiles/engine_com.dir/src/cmd/beam_generic.o' failed
make[2]: *** [CMakeFiles/engine_com.dir/src/cmd/beam_generic.o] Error 1
CMakeFiles/Makefile2:262: recipe for target 'CMakeFiles/engine_com.dir/all' failed
make[1]: *** [CMakeFiles/engine_com.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
可以找到physics.h文件here
我有一种感觉,以前只要有一个 infile 声明就足以为编译器提供 "preference",但现在情况并非如此。如果有人能解释这背后的问题,我将不胜感激,以便我将来更好地解决它。
我试过将其注释掉,这会导致更深入的代码段(超过 4000 行)出现歧义错误。
编辑
在原型前面应用 constexpr 只是将 constexpr 添加到错误消息中。
删除并强制所有人使用标准库版本导致
/usr/include/c++/6/cmath:1288:3: note: candidate: constexpr float std::copysign(float, float)
copysign(float __x, float __y)
^~~~~~~~
/projects/Vegastrike/engine/src/cmd/unit_generic.cpp:633:7: note: candidate: float copysign(float, float)
float copysign( float x, float y )
^~~~~~~~
/projects/Vegastrike/engine/src/cmd/unit_generic.cpp:3443:61: error: call of overloaded ‘copysign(float, const float&)’ is ambiguous
Res.j = copysign( fuelclamp*limits.vertical, amt1.j );
^
In file included from /usr/include/features.h:364:0,
from /usr/include/x86_64-linux-gnu/c++/6/bits/os_defines.h:39,
from /usr/include/x86_64-linux-gnu/c++/6/bits/c++config.h:502,
from /usr/include/c++/6/bits/stl_algobase.h:59,
from /usr/include/c++/6/bits/stl_tree.h:63,
from /usr/include/c++/6/set:60,
from /projects/Vegastrike/engine/src/cmd/unit_generic.cpp:4:
只需在前向声明前加上'constexpr',使其与cmath中的声明匹配。
我认为如果你以正确的方式斜视它,那么代码就不是 well-formed C++,尽管它是 well-formed C:
C 允许用户代码声明来自 C 标准库的名称并且 不 包含相关的 header.
C++ 不 允许用户代码(重新)声明名称空间 std
.
C++的"C headers"(附件D)说,名字是否先在命名空间std
in cname中声明,然后拉入name.h 中的全局命名空间通过 using-declaration 或反之亦然。因此,您必须假设当您在 C++ 中使用兼容性 header name.h 并使用全局名称时,该名称可能已在名称空间 std
中声明并且全局命名空间包含 using-declaration,因此您不能声明该名称。
简而言之,并非所有 C 代码都是有效的 C++,您已经找到了一个例子。您的问题的具体原因是您的 C++ 库已选择将 constexpr
添加到其 copysign
的声明中,这是允许的,因为它假定您没有声明其名称。
答案当然是至少,就进一步推进编译进度而言,是将有问题的函数包装在一个名称中 space。
感谢提供解决方案的人。
我正在尝试解决与现在看来已过时的开源游戏相关的问题。当我想玩它时,我正在尝试构建它并可能向其中添加一些东西。
不幸的是,我遇到了一些问题,我的 C++ 技能确实欠缺。
In file included from /home/talrose/projects/Vegastrike/engine/src/cmd/../gfx/camera.h:24:0,
from /home/talrose/projects/Vegastrike/engine/src/cmd/beam_generic.cpp:8:
/home/talrose/projects/Vegastrike/engine/src/physics.h:30:34: error: ‘float copysign(float, float)’ conflicts with a previous declaration
float copysign( float x, float y );
^
In file included from /usr/include/c++/6/math.h:36:0,
from /projects/Vegastrike/engine/src/vs_math.h:27,
from /projects/Vegastrike/engine/src/vegastrike.h:36,
from /projects/Vegastrike/engine/src/cmd/beam_generic.cpp:1:
/usr/include/c++/6/cmath:1288:3: note: previous declaration ‘constexpr float std::copysign(float, float)’
copysign(float __x, float __y)
^~~~~~~~
CMakeFiles/engine_com.dir/build.make:614: recipe for target 'CMakeFiles/engine_com.dir/src/cmd/beam_generic.o' failed
make[2]: *** [CMakeFiles/engine_com.dir/src/cmd/beam_generic.o] Error 1
CMakeFiles/Makefile2:262: recipe for target 'CMakeFiles/engine_com.dir/all' failed
make[1]: *** [CMakeFiles/engine_com.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
可以找到physics.h文件here
我有一种感觉,以前只要有一个 infile 声明就足以为编译器提供 "preference",但现在情况并非如此。如果有人能解释这背后的问题,我将不胜感激,以便我将来更好地解决它。
我试过将其注释掉,这会导致更深入的代码段(超过 4000 行)出现歧义错误。
编辑
在原型前面应用 constexpr 只是将 constexpr 添加到错误消息中。
删除并强制所有人使用标准库版本导致
/usr/include/c++/6/cmath:1288:3: note: candidate: constexpr float std::copysign(float, float) copysign(float __x, float __y) ^~~~~~~~ /projects/Vegastrike/engine/src/cmd/unit_generic.cpp:633:7: note: candidate: float copysign(float, float) float copysign( float x, float y ) ^~~~~~~~ /projects/Vegastrike/engine/src/cmd/unit_generic.cpp:3443:61: error: call of overloaded ‘copysign(float, const float&)’ is ambiguous Res.j = copysign( fuelclamp*limits.vertical, amt1.j ); ^ In file included from /usr/include/features.h:364:0, from /usr/include/x86_64-linux-gnu/c++/6/bits/os_defines.h:39, from /usr/include/x86_64-linux-gnu/c++/6/bits/c++config.h:502, from /usr/include/c++/6/bits/stl_algobase.h:59, from /usr/include/c++/6/bits/stl_tree.h:63, from /usr/include/c++/6/set:60, from /projects/Vegastrike/engine/src/cmd/unit_generic.cpp:4:
只需在前向声明前加上'constexpr',使其与cmath中的声明匹配。
我认为如果你以正确的方式斜视它,那么代码就不是 well-formed C++,尽管它是 well-formed C:
C 允许用户代码声明来自 C 标准库的名称并且 不 包含相关的 header.
C++ 不 允许用户代码(重新)声明名称空间 std
.
C++的"C headers"(附件D)说,名字是否先在命名空间std
in cname中声明,然后拉入name.h 中的全局命名空间通过 using-declaration 或反之亦然。因此,您必须假设当您在 C++ 中使用兼容性 header name.h 并使用全局名称时,该名称可能已在名称空间 std
中声明并且全局命名空间包含 using-declaration,因此您不能声明该名称。
简而言之,并非所有 C 代码都是有效的 C++,您已经找到了一个例子。您的问题的具体原因是您的 C++ 库已选择将 constexpr
添加到其 copysign
的声明中,这是允许的,因为它假定您没有声明其名称。
答案当然是至少,就进一步推进编译进度而言,是将有问题的函数包装在一个名称中 space。
感谢提供解决方案的人。