任何人都可以帮忙告诉我为什么参数演绎不符合我的预期吗?请参阅我的代码评论我的思路?
#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;
}
答案 0 :(得分:0)
我将依次处理你的每一条评论。
deduce1
与d
:
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
。指针指向的int
是const
。如果您要报告所指向类型的const
,则在检查remove_pointer
之前,您需要使用const
。因此,您可以将const
检查更改为:
cout << "Is const: " << boolalpha << is_const<typename remove_pointer<T>::type>::value << endl;
然而,之前给出的结果是正确答案。指针确实不是const
。实际上,即使指针为const
,顶级consts
也会在类型扣除完成之前被删除,因此T
无论如何都不会const
。这样做的原因是,如果你通过值传递,你实际上并不关心参数的const
,因为你无论如何都要复制它。
deduce2
与b
:
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
完全符合预期。
deduce2
与c
:
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
进行修复。
deduce2
与d
:
int const d[] = {12};
deduce2(d,"int const d[] = {12}"); // would have thought is_const<T> would return true
与deduce1
d
(第1项)相同的问题。
deduce3
与c
:
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项)相同的问题。
deduce3
与d
:
int const d[] = {12};
deduce3(d,"int const d[] = {12}"); // would have thought is_const<T> would return true
与deduce1
d
(第1项)相同的问题。
deduce3
与string("Hello")
:
deduce3(string("Hello"),"string(\"Hello\")"); // why not rvalue reference
我假设您对“通用引用”有所了解。 Scott Meyers在这个问题上有一个很棒的article和talk。
在这种情况下,由于string("Hello")
是一个右值表达式,因此T
类型推导为string
(由T&&
形式的推导的右值引用类型的规则推导出来)。 args
的类型现在为string &&
。因此,如果你检查decltype(args)
是否是左值,它会说是真的。但T
本身并非如此。
如果您修复了代码,以便T
上的所有类型特征现在都在decltype(args)
,那么您将遇到新问题。当args属于引用类型时,您希望为const
的某些类型不会。那是因为没有const
引用这样的东西。与在第1项中使用remove_pointer
类似,您需要使用remove_reference
来获取基础类型并检查它是否为const
。