c++ - 如何使用类型特征正确推断引用的参数
问题描述
我正在尝试计算模板的传递方法签名中的参数数量。我想知道参数的数量,因为这个方法被包装在一个通用的 lamda 中,并且根据传递的参数的数量,我将在此处传递的方法中添加更多信息。
我已将问题隔离到下面的代码段。下面的代码片段按预期工作,但是一旦我更改结果方法以引用 METHOD,编译失败。为什么对参数类型的引用会影响类型?我怎样才能使它与参考一起工作?
使用 Microsoft Visual Studio 2017 对此进行了测试。
#include "pch.h"
#include <iostream>
template <typename Func>
struct func_traits;
template <typename R, typename... TArgs>
struct func_traits<R(*)(TArgs...)> {
static constexpr uint32_t ARG_COUNT = sizeof...(TArgs);
};
class TestClass {
public:
// Compile error!!!
// error C2027: use of undefined type 'func_traits<METHOD>'
// uint32_t Result(const METHOD& function)
template <typename METHOD>
uint32_t Result(const METHOD function) {
return (func_traits< METHOD >::ARG_COUNT);
}
};
void foo(int a, int b, int c)
{
}
int bar()
{
return 0;
}
int baz(double)
{
return 0;
}
int main()
{
TestClass device;
std::cout << device.Result(foo) << std::endl;
std::cout << device.Result(bar) << std::endl;
std::cout << device.Result(baz) << std::endl;
return 0;
}
解决方案
您的示例中的场景非常罕见,并且与特定于函数和数组的特定模板规则有关。
详细说明如果您有一个模板函数通过引用获取另一个函数,那么为 T 推导的类型是实际函数类型(不是指向函数的指针)。例如
template<typename T>
void fun(const T& f);
{
.....
}
void print(int);
fun(print); //for this case T will be deduced as void(int) and not void(*)int i.e. T will not be a function pointer
因此,要让您的示例适用于参考案例,您必须再创建一个模板专业化,例如:
template <typename R, typename... TArgs>
struct func_traits<R(TArgs...)> {
static constexpr uint32_t ARG_COUNT = sizeof...(TArgs);
}; //note (*) is removed from template function
简而言之,如果您通过值传递函数或数组,那么它们将衰减为指针,但如果您通过引用传递,那么它们将被视为原样。 更多细节可在 Scott Meyers Effective Modern C++ ( https://www.oreilly.com/library/view/effective-modern-c/9781491908419/ch01.html )
推荐阅读
- python - BeautifulSoup 从图表样式中获取价值
- bash - Bash 命令指定要搜索的 egrep
- oracle - 如何从 bash 运行 ODI12c 映射以自动化 ODI 映射过程
- python - 我应该以非 root 用户身份安装 Python 包还是设置一个虚拟环境将它们安装在 Docker 容器中?
- visual-studio-code - VS 代码是否有像我们在 spyder 中一样的变量资源管理器对象?
- node.js - Google Cloud Run 未按预期扩展
- android - 无效的密钥库格式博览会反应原生
- html - 使用css的底部边框圆角
- c - 如何使用从 C 中的另一个文件导入的函数处理文件处理?
- arrays - 如何循环遍历二维数组以在页面上显示数据?