从函数指针对标准 C++98 中的函数类型参数进行静态推理

Static inference of function type argument in standard C++98 from function pointer

提问人:Fabio 提问时间:1/8/2018 最后编辑:BrhakaFabio 更新时间:6/26/2019 访问量:341

问:

我有一个导出一元函数的共享库,例如:

extern "C" void foo(int);
extern "C" void zoo(double);

该库由不支持 C++ 11 的编译器使用。我想从函数名称静态推断结构中的函数类型。

我可以写:

template <typename T, void(*)(T)> struct A{ typedef T arg_t; };

为此,我必须在实例化模板时显式指定类型,即我必须编写T

A<int, &foo>

而不仅仅是

A<&foo>

鉴于此信息嵌入在指针类型中,有没有办法静态提取信息?

C++ 模板 C++98

评论

4赞 StoryTeller - Unslander Monica 1/8/2018
直到 C++17 才添加了对类似内容的支持。如果没有C++11,我认为在标准C++中是不可能的。A<&foo>
0赞 MSalters 1/8/2018
这可能是一个 XY 问题。如果你写一个助手,你可以写 .template<typename T> T get_return_type(void(*)(T))decltype(get_return_type(&foo))
1赞 Fabio 1/8/2018
@MSalters:如果 JUST 没有 C++11,那将是一个解决方案。decltype
0赞 Maxim Egorushkin 1/9/2018
您可以在函数模板中执行此操作,但不幸的是,否则就不能执行此操作。

答:

0赞 emerg.reanimator 5/23/2018 #1

我不确定为什么您只需要在结构 A 中定义一个新类型。 假设它内部有一个 T 类型的变量 v。 在这种情况下,我将使用 C++ 函数重载功能,如下所示:

#include <stdio.h>

extern "C"
{
    void foo(int x) { printf("foo(%i)\n", x); }
    void zoo(double x) { printf("zoo(%f)\n", x); }
}


template <typename T> struct A { typedef T arg_t; arg_t v; };


void foo_zoo(int x) { foo(x); }
void foo_zoo(double x) { zoo(x); }
void foo_zoo(A<int> x) { foo(x.v); }
void foo_zoo(A<double> x) { zoo(x.v); }


int main(int argc, char **argv)
{
    int xi = 1;
    double xd = 2.0;

    A<int> ai; ai.v = 10;
    A<double> ad; ad.v = 20.0;

    foo_zoo(xi);
    foo_zoo(xd);

    foo_zoo(ai);
    foo_zoo(ad);

    return 0;
}

在这种情况下,编译器/链接器将使用正确版本的foo_zoo函数,而不会产生任何运行时开销。如果需要,可以通过链接来消除foo_zoo未使用的版本。