64,646
社区成员
发帖
与我相关
我的任务
分享
class A{
int m_i;
public:
A():m_i(10){}
int& Get(){return m_i;}
};
int main(int argc, char* argv[])
{
A obj;
auto i=obj.Get();
i=20;
printf("%d\n",obj.Get());
decltype(obj.Get()) ii=obj.Get();
ii=30;
printf("%d\n",obj.Get());
return 0;
}
auto i=forward<int&>(obj.Get());
int* GetP(){return &m_i;}
然后main函数里面如果
auto p=obj.GetP();
那么这个auto就能自动推导出p是一个指针了。你不是说"D是由指针声明符或引用声明符与identifier一起组合而成的"吗? 看起来指针的处理和引用的处理还不太一样啊。
还请继续解释,谢谢![/quote]
所以说,看模板推导规则了。
WG21/N3797
7.1.6.4
4 The type of a variable declared using auto or decltype(auto) is deduced from its initializer. This use is allowed when declaring variables in a block (6.3), in namespace scope (3.3.6), and in a for-init-statement (6.5.3).
auto or decltype(auto) shall appear as one of the decl-specifier s in the decl-specifier-seq and the declspecifier-seq shall be followed by one or more init-declarator s, each of which shall have a non-empty initializer . In an initializer of the form
( expression-list )
the expression-list shall be a single assignment-expression .
[ Example:
auto x = 5; // OK: x has type int
const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int
static auto y = 0.0; // OK: y has type double
auto int r; // error: auto is not a storage-class-specifier
auto f() -> int; // OK: f returns int
auto g() { return 0.0; } // OK: g returns double
auto h(); // OK: h’s return type will be deduced when it is defined
—end example ]
7 When a variable declared using a placeholder type is initialized, or a return statement occurs in a function
declared with a return type that contains a placeholder type, the deduced return type or variable type
is determined from the type of its initializer. In the case of a return with no operand, the initializer is
considered to be void(). Let T be the declared type of the variable or return type of the function. If the
placeholder is the auto type-specifier , the deduced type is determined using the rules for template argument
deduction. If the deduction is for a return statement and the initializer is a braced-init-list (8.5.4), the
program is ill-formed. Otherwise, obtain P from T by replacing the occurrences of auto with either a
new invented type template parameter U or, if the initializer is a braced-init-list , with std::initializer_-list<U>. Deduce a value for U using the rules of template argument deduction from a function call (14.8.2.1),
where P is a function template parameter type and the initializer is the corresponding argument. If the
deduction fails, the declaration is ill-formed. Otherwise, the type deduced for the variable or return type is
obtained by substituting the deduced U into P. [ Example:
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
—end example ]
[ Example:
const auto &i = expr;
The type of i is the deduced type of the parameter u in the call f(expr) of the following invented
function template:
template <class U> void f(const U& u);
—end example ]
If the placeholder is the decltype(auto) type-specifier , the declared type of the variable or return type
of the function shall be the placeholder alone. The type deduced for the variable or return type is determined
as described in 7.1.6.2, as though the initializer had been the operand of the decltype. [ Example:
int i;
int&& f();
auto x3a = i; // decltype(x3a) is int
decltype(auto) x3d = i; // decltype(x3d) is int
auto x4a = (i); // decltype(x4a) is int
decltype(auto) x4d = (i); // decltype(x4d) is int&
auto x5a = f(); // decltype(x5a) is int
decltype(auto) x5d = f(); // decltype(x5d) is int&&
auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
auto *x7a = &i; // decltype(x7a) is int*
decltype(auto)*x7d = &i; // error, declared type is not plain decltype(auto)
—end example ]
14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]
1
Template argument deduction is done by comparing each function template parameter type (call it P) with
the type of the corresponding argument of the call (call it A) as described below. If removing references
and cv-qualifiers from P gives std::initializer_list<P
0
> for some P
0
and the argument is an initializer
list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P
0
as a function
template parameter type and the initializer element as its argument. Otherwise, an initializer list argument
causes the parameter to be considered a non-deduced context (14.8.2.5). [ Example:
template<class T> void f(std::initializer_list<T>);
f({1,2,3}); // T deduced to int
f({1,"asdf"}); // error: T deduced to both int and const char*
template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T
—end example ] For a function parameter pack that occurs at the end of the parameter-declaration-list ,
the type A of each remaining argument of the call is compared with the type P of the declarator-id of the
function parameter pack. Each comparison deduces template arguments for subsequent positions in the
template parameter packs expanded by the function parameter pack. When a function parameter pack
appears in a non-deduced context (14.8.2.5), the type of that parameter pack is never deduced. [ Example:
template<class ... Types> void f(Types& ...);
template<class T1, class ... Types> void g(T1, Types ...);
template<class T1, class ... Types> void g1(Types ..., T1);
void h(int x, float& y) {
const int z = x;
f(x, y, z); // Types is deduced to int, float, const int
g(x, y, z); // T1 is deduced to int; Types is deduced to float, int
g1(x, y, z); // error: Types is not deduced
g1<int, int, int>(x, y, z); // OK, no deduction occurs
}
—end example ]
2
If P is not a reference type:
— If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is
used in place of A for type deduction; otherwise,
— If A is a function type, the pointer type produced by the function-to-pointer standard conversion (4.3)
is used in place of A for type deduction; otherwise,
— If A is a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction.
以下超过字符限制略。
int* GetP(){return &m_i;}
然后main函数里面如果
auto p=obj.GetP();
那么这个auto就能自动推导出p是一个指针了。你不是说"D是由指针声明符或引用声明符与identifier一起组合而成的"吗? 看起来指针的处理和引用的处理还不太一样啊。
还请继续解释,谢谢!