工具/软件:TI C/C++编译器
在我的应用中、我必须在函数指针中存储 fmod、pow、atan2、fmax 和 fmin 的双过载地址。 这在 CGT 8.3.x 中很难实现(我测试了8.3.0和8.3.6)。
尝试编译:
//最小示例
#include
int main()
{
double works = fmod (1.0、3.0);
auto broken = static_cast (&FMod);
返回工作!=断开(1.0、3.0);
}
使用命令:
$cgt_path/bin/cl6x -i$cgt_path/include overload_resolution.cpp
产生以下输出:
"μ C/ti-CGT-C6000_8.3.6/include/libcxx/math.h"、第893行:~:静态断言失败、出现"" 在"std:__2:__lazy_enable_if<的实例化期间检测到 ,std::__2:__promote <_A1, _A2, void>:在 编译"overy_resolution .cpp"时检测到"overy_resolution.cppp"的第6行中键入 fmod (_A1、_A2)[带_a1=double、_a2=double]"。 >>编译失败
GCC、clang 和 MSVC 均可编译此最小示例、而不会出现任何问题。
查看断言、编译器决定在$cgt_path/include/libcxx/math.h 中定义的模板与在$cgt_path/include/math.h 中声明的 C 函数 double fmod (double、double)的匹配
进一步的分析表明、编译器得出这一结论是因为模板具有正常的 C++链接、而 C 函数具有'extern "C"链接:
//分析 extern "C" double foo (double、double) { return 0.0; } 模板 t3 foo (t1、t2) { static_assert (sizeof (t1)=0、"选择的错误过载"); return 1.0; } int main() { auto fp = static_cast (&foo); 返回 static_cast (fp (1.0、2.0)); }
产生的
"OVERLOAD_RESolution.cpp"、第10行:错误:静态断言失败、并显示"Selected Wrong OVERLOAD (选择了错误的过载)" 在 "overy_resolution.cpp"编译中检测到的第16行"T3 foo (T1、T2)[ t1=double、t2=double、t3=double]"实例化期间检测到错误。 >>编译失败
而
//分析
/*extern "C"*/ double foo (double、double)
{
返回0.0;
}
模板
t3 foo (t1、t2)
{
static_assert (sizeof (t1)=0、"选择的错误过载");
return 1.0;
}
int main()
{
auto fp = static_cast (&foo);
返回 static_cast (fp (1.0、2.0));
}
编译而不会出现问题。
我可以想象、模板与'extern "C"函数的匹配是正确的、但我希望有一个具有 C++链接的包装程序(类似于 float fmod (float、float))。
在找出根本原因后、我获得了一个可以编译的权变措施:
//变通办法
#include
extern "C"
{
auto cppfmod = static_cast (&FMOD);
}
int main()
{
double works = FMod (1.0, 3.0);
auto broken = cpfmod;
return works!= broken (1.0, 3.0);
}
