为什么将 `printf` 作为模板函数参数传递成功但 `cos` 失败(msvc 19)?

Why passing `printf` as template function argument succeeds but `cos` failed (msvc 19)?

我在 link 上玩了一下在线 C++ 编译器。但是下面的代码片段在使用 msvc v19.latest.

编译时失败了
#include <iostream>
#include <cmath>
#include <cstdio>

template<class F, class...L>
void test(F f, L...args) {
    std::cout<< "res = " << f(args...) << '\n';
}


int main() 
{
    test(cos, 0.1);   #1
    test(printf, "%s", "aaa");   #2
}

怎么可能2号线没问题,1号线就通不过呢?

MSVC 对以下代码很满意,但这次轮到 GCC 拒绝了。 MSVC 的 iostream 文件包括 cmath 头和 GCC #undefs cos :)

#include <stdio.h>
#include <math.h>
//#include <iostream>

template<class F, class...L>
void test(F f, L...args) {
    f(args...);
}

int main() 
{
    test(cos, 0.1);
    test(printf, "%s", "aaa");
}

从 c++20 开始,第二个答案中提出了另一个问题,并已在这个问题中得到解决

它失败了,因为 cos 是 msvc 中的重载函数。这意味着至少有 3 个不同版本的 cos:

float cos(float arg);
double cos(double arg);
long double cos(long double arg);

编译器无法猜测您要使用哪个,但您可以使用 static_cast 来帮助它,如下所示:

int main()
{
    test(static_cast<double(*)(double)>(cos), 0.1);
    test(printf, "%s", "aaa");   
}

not allowed获取库函数的地址(有少数例外),然后将其作为参数传递给另一个函数。任何这样做的尝试都是未指明的行为。 MSVC 拒绝你的程序是对的,gcc 接受它也是对的(并且可能格式化你的硬盘并向你的老板发送讨厌的电子邮件)。