强制从函数中推导模板以在适用时产生const引用

时间:2019-10-02 18:48:37

标签: c++ c++11 templates variadic-templates

在vscode中使用gdb运行以下函数会告诉我,T (*)(const int &, const int *, int &, int)形式的函数推导的argType是int const int * int &和{{1} } 分别。当出现int参数时,是否有任何方法可以强制编译器推断const Type &?还是我可以通过其他方法以有用的方式提取类型信息?

const Type &

编辑: 多一点上下文:该函数显然什么也没有做,但是产生它的问题函数也接受所有要与f一起运行的参数,而不是推导出而是将其转换。 这给不可复制的对象用作const引用提出了一个问题。

使用#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; } } 的示例如下:

testfunc

1 个答案:

答案 0 :(得分:2)

这里的问题是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