gpt4 book ai didi

C++模板参数推导过程

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:23:54 24 4
gpt4 key购买 nike

任何人都可以帮助我解释为什么论证推导没有像我预期的那样工作吗?请查看我的代码注释以了解我的思路?

#include <iostream>
#include <type_traits>
#include <iomanip>
#include <string>

using namespace std;

template<class T>
void deduce1(T args, string arg){
cout << "template<class T> void deduce1(T args) " << " argument passed in was: " << arg << " deduced as: " << typeid(T).name() << endl;
cout << "Is const: " << boolalpha << is_const<T>::value << endl;
cout << "Is reference: " << boolalpha << is_reference<T>::value << endl;
cout << "Is pointer: " << boolalpha << is_pointer<T>::value << endl;
}

template<class T>
void deduce2(T& args,string arg){
cout << "template<class T> void deduce2(T args) " << " argument passed in was: " << arg << " deduced as: " << typeid(T).name() << endl;
cout << "Is const: " << boolalpha << is_const<T>::value << endl;
cout << "Is reference: " << boolalpha << is_reference<T>::value << endl;
cout << "Is pointer: " << boolalpha << is_pointer<T>::value << endl;
}

template<class T>
void deduce3(T&& args,string arg){
cout << "template<class T> void deduce3(T args) " << " argument passed in was: " << arg << " deduced as: " << typeid(T).name() << endl;
cout << "Is const: " << boolalpha << is_const<T>::value << endl;
cout << "Is reference: " << boolalpha << is_reference<T>::value << endl;
cout << "Is rvalue reference: " << boolalpha << is_rvalue_reference<T>::value << endl;
cout << "Is pointer: " << boolalpha << is_pointer<T>::value << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{

int a = 1;
const int b = 5;
int c[] = {12};
int const d[] = {12};
int& e = a;

deduce1(a,"int a = 1");
deduce1(b,"const int b = 5");
deduce1(c,"int c[] = {12}");
deduce1(d,"int const d[] = {12}"); // would have thought is_const<T> would return true any comments?
deduce1(e,"int& e = a");
deduce1(5,"5");

deduce2(a,"int a = 1");
deduce2(b,"const int b = 5"); //would have though type would be deduced as int const comments?
deduce2(c,"int c[] = {12}"); // why is this not returning true as a reference?
deduce2(d,"int const d[] = {12}"); // would have thought is_const<T> would return true any comments
deduce2(e,"int& e = a");

deduce3(a,"int a = 1");
deduce3(b,"const int b = 5");
deduce3(c,"int c[] = {12}"); // why is this not returning true as a reference?
deduce3(d,"int const d[] = {12}"); // would have thought is_const<T> would return true any comments
deduce3(e,"int& e = a");
deduce3(string("Hello"),"string(\"Hello\")"); // why not rvalue reference


return 0;
}

最佳答案

我会依次处理您的每条评论。

  1. deduce1d:

    template <class T> void deduce1(T args, string arg);
    int const d[] = {12};
    deduce1(d, "int const d[] = {12}"); // would have thought is_const<T> would return true

    首先重要的是,在 C++ 中,您不能按值将数组作为参数传递。表示数组的表达式几乎会立即衰减为指向其第一个元素的指针。所以此处为 T 推导的类型将是 int const *

    那么,为什么这行不通呢?问题是指针 不是const。指针指向的 intconst。如果您想报告所指向类型的 constness,您需要在检查 constness 之前使用 remove_pointer。因此,您可以将 const 检查更改为:

    cout <<  "Is const: " << boolalpha << is_const<typename remove_pointer<T>::type>::value << endl;

    但是,它之前给出的结果是正确答案。指针确实不是 const。事实上,即使指针是 const,顶层 const 也会在类型推导完成之前被剥离,所以 T 不会是 const 无论如何。这样做的原因是,如果你按值传递,你真的不关心参数的 constness,因为你无论如何都要复制它。

  2. deduce2b:

    template <class T> void deduce2(T& args,string arg);
    const int b = 5;
    deduce2(b,"const int b = 5"); //would have though type would be deduced as int const

    不确定这里发生了什么,但我的输出是:

    deduced as: i
    Is const: true
    Is reference: false
    Is pointer: false

    完全符合预期。

  3. deduce2c:

    int c[] = {12};
    deduce2(c,"int c[] = {12}"); // why is this not returning true as a reference?

    这是说它不是引用,原因与所有 deduce2 调用都这么说一样(并且您在整个 deduce3 中也有这个问题)。在您的函数中,您正在检查 T 的类型,但 args 的类型是 T&。您只检查 & 之前的部分。所以在这里,args 的类型是 int (&)[1] c 但您只是检查 int [1] 是否是引用。通过在检查中使用 decltype(args) 而不是 T 来修复它。

  4. deduce2d:

    int const d[] = {12};
    deduce2(d,"int const d[] = {12}"); // would have thought is_const<T> would return true

    deduce1 相同的问题与 d(第 1 项)。

  5. deduce3c:

    template <class T> void deduce3(T&& args,string arg);
    int c[] = {12};
    deduce3(c,"int c[] = {12}"); // why is this not returning true as a reference?

    deduce2 使用 c(第 3 项)的问题相同。

  6. deduce3d:

    int const d[] = {12};
    deduce3(d,"int const d[] = {12}"); // would have thought is_const<T> would return true

    deduce1 相同的问题与 d(第 1 项)。

  7. 使用string("Hello")推导3:

    deduce3(string("Hello"),"string(\"Hello\")"); // why not rvalue reference

    我假设您对“通用引用”有所了解。斯科特迈耶斯有一个伟大的articletalk关于这个问题。

    在这种情况下,因为 string("Hello") 是一个右值表达式,类型 T 被推断为 string(由T&& 形式的推导右值引用类型的规则)。 args 的类型现在是 string &&。因此,如果您检查 decltype(args) 是否为右值,它会说 true。但是 T 本身不是。

如果您修复代码,使 T 上的所有类型特征现在都在 decltype(args) 上,您将遇到新问题。当 args 是引用类型时,您期望为 const 的某些类型将不会。那是因为没有 const 引用这样的东西。与在项目 1 中使用 remove_pointer 类似,您需要使用 remove_reference 获取基础类型并检查它是否为 const

关于C++模板参数推导过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13265842/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com