为什么这些C++案例实例化不同的模板

Why these C++ cases instantiate different templates

本文关键字:实例化 C++ 案例 为什么      更新时间:2023-10-16

>我正在尝试编写一些功能,我需要保存不同的函数,然后提取它们的参数类型。所以我使用函数签名作为模板参数。但我得到了一些意想不到的结果。代码如下:

#include <functional>
#include <iostream>
template <class T>
struct foo
{
    foo()
    {
        std::cout << "class T" << std::endl;
    }
};
template <class Ret, class Arg>
struct foo<Ret(Arg)>
{
    foo()
    {
        std::cout << "Ret(Arg)" << std::endl;
    }
};
template <class T>
void save(std::function<T>)
{
    new foo<T>();
}
int main(int argc, char* argv[])
{
    std::function<void(void)> someFoo;
    save(someFoo);
    return 0;
}

因此,如果变量 someFoo 是类型为 void(void) 的函数,它会实例化第一个模板,foo<T> 。但是如果我将其更改为 void(int) ,那么我会实例化所需的专用模板。为什么?

在C++中,有一个void参数实际上与根本没有参数是一样的(顺便说一下,与C不同)。所以它会匹配Ret()的专业化,但它不能匹配Ret(Arg)的专业化。

void(void)

void()完全相同 - 第二个void是可选的,没有区别。

这就是使用第一个没有参数的模板的原因。