为什么这些 C++ 案例实例化不同的模板
Why these C++ cases instantiate different templates
我正在尝试编写一些功能,我需要在其中保存不同的函数,然后提取它们的参数类型。所以我使用函数签名作为模板参数。但是我得到了一些意想不到的结果。
这是代码:
#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)
,那么我将实例化所需的专用模板。这是为什么?
void(void)
与 void()
完全相同 - 第二个 void
是可选的,没有区别。
这就是为什么使用第一个没有参数的模板的原因。
在 C++ 中,有一个 void
参数实际上等同于根本没有参数(顺便说一句,这与 C 中不同)。所以它会匹配 Ret()
的专业化,但不能匹配 Ret(Arg)
.
的专业化
我正在尝试编写一些功能,我需要在其中保存不同的函数,然后提取它们的参数类型。所以我使用函数签名作为模板参数。但是我得到了一些意想不到的结果。 这是代码:
#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)
,那么我将实例化所需的专用模板。这是为什么?
void(void)
与 void()
完全相同 - 第二个 void
是可选的,没有区别。
这就是为什么使用第一个没有参数的模板的原因。
在 C++ 中,有一个 void
参数实际上等同于根本没有参数(顺便说一句,这与 C 中不同)。所以它会匹配 Ret()
的专业化,但不能匹配 Ret(Arg)
.