新的auto关键字不能取得"引用"的类型啊,为什么?
我有下面一小段代码,我想用auto关键字返回一个引用,然后改变这个引用的值。我发现不成功。
the deduction fails, the declaration is ill-formed.
[解决办法]
要引用的话,目前只能用 decltype 了。
[解决办法]
int* GetP(){return &m_i;}
auto p=obj.GetP();
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.
以下超过字符限制略。