强制从函数中推导模板以生成常量引用(如果适用)
Force template deduction from a function to produce const references where applicable
在vscode 中使用 gdb 运行以下函数告诉我,T (*)(const int &, const int *, int &, int)
形式函数的推导 argType 分别是int
const int *
int &
和int
。有没有办法强制编译器在呈现const Type &
参数时推断const Type &
?或者是否有其他方法可以以有用的方式提取该类型信息?
#include<typeinfo>
template<typename T, typename...argTypes>
void testfunc(T (*f)(argTypes...))
{
const char *a[] = { typeid(argTypes).name()... };
for(auto &av :a)
{
std::cout << av << std::endl;
}
}
编辑: 更多上下文:这个函数显然几乎没有什么作用,但是产生它的问题函数也接受了所有使用 f 运行的参数,它们不是被推导的,而是被转换的。 这给将不可复制的对象用作 const 引用带来了问题。
使用testfunc
的示例如下:
#include "testfunc.h"
std::vector<bool> funcToTest(const int &a, const int *b, int &c, int d)
{
std::vector<bool> out;
out.push_back(&a == b);
out.push_back(&c == b);
out.push_back(&d == b);
return out;
}
int main()
{
// put a breakpoint here, and step in, you would see that 'a'
// describes the situation as described above.
testfunc(funcToTest);
}
这里的问题在于typeid
,而不是模板推导。 如果您使用
template<typename... Ts>
struct types;
template<typename T, typename...argTypes>
void testfunc(T (*f)(argTypes...))
{
types<argTypes...>{};
}
您会收到一条很好的错误消息,例如
main.cpp: In instantiation of 'void testfunc(T (*)(argTypes ...)) [with T = std::vector<bool>; argTypes = {const int&, const int*, int&, int}]':
main.cpp:30:24: required from here
main.cpp:12:5: error: invalid use of incomplete type 'struct types<const int&, const int*, int&, int>'
12 | types<argTypes...>{};
| ^~~~~
main.cpp:7:8: note: declaration of 'struct types<const int&, const int*, int&, int>'
7 | struct types;
| ^~~~~
这表明函数参数类型已正确推导。
typeid
如果类型是引用,则返回引用的类型,则返回引用的类型。 它还会删除类型上的所有 cv 限定。 这意味着
int main()
{
std::cout << typeid(int).name() << "n";
std::cout << typeid(int&).name() << "n";
std::cout << typeid(const int).name() << "n";
std::cout << typeid(const int&).name() << "n";
std::cout << typeid(volatile int).name() << "n";
std::cout << typeid(volatile int&).name() << "n";
std::cout << typeid(const volatile int).name() << "n";
std::cout << typeid(const volatile int&).name() << "n";
}
指纹
i
i
i
i
i
i
i
i
相关文章:
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 为什么我可以通过引用修改常量返回
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 将常量指针引用绑定到非常量指针
- 通过常量引用传递参数的矩阵模板类
- 按值捕获引用时出现非常量
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么按值传递QStringView比引用常量更快?
- 通过引用常量函数调用另一个类的非常量函数
- 构造常量对象与引用常量对象
- 引用“常量value_type”时出错
- 为什么可以在 for 语句中重新分配引用常量
- 程序反馈:命名循环索引和引用常量数据
- 堆还是栈?在c++中函数调用中引用常量字符串时
- 为什么常量结构数组在按名称引用常量结构时不放在 .rodata 中?
- 为什么编译器允许在函数中发送对迭代器的引用,该函数引用常量迭代器