Domanda

Potete per favore me spiegare la differenza tra il meccanismo di quanto segue:

int function();

template<class T>
void function2(T&);

void main() {
    function2(function()); // compiler error, instantiated as int &

    const int& v = function();
    function2(v); // okay, instantiated as const int&
}

è il mio ragionamento corrette in riferimento alla creazione di istanze? perché non è la prima istanziato come const T&?

Grazie

È stato utile?

Soluzione

A causa restituisce function un valore non-const. solo gli oggetti può essere const, perché memorizzano qualche stato che potrebbe essere modificato se non fosse const. Quello che di ritorno non c'è un oggetto, ma un valore puro. Concettualmente, non sono modificabili (come le costanti di enumerazione, per esempio), ma non sono const qualificati (come, ancora una volta, le costanti di enumerazione).

Altri suggerimenti

I think that you might be confused between rvalues and the const qualifier. function returns a non-const rvalue temporary of type int, so the compiler deduces T to be int, as it should. As you point out, you can bind a temporary to a const ref (c++03 12.2/5), but the compiler will not add cv qualifiers to make a function call well formed. Since you can't control the template function, there are two ways around this (in addition to the solution you posted).

(1) Explicit template parameters: function2<const int>(function())

(2) cv qualify return: const int function();

Both of these solutions are well formed. (1) seems the better solution, IMHO, since (2) is unconventional and silly.

Edit: Actually, the deduced type can be more cv-qualified than the argument for a ref template argument, but only if type deduction would otherwise fail (c++03 14.8.2.1/3). In this case, type deduction doesn't fail, but results in a malformed function call (SFINAE does not apply, because the template function specialization itself is not malformed).

If the intent of the template author was to not modify the argument, it should be declared as a const reference argument, so this may be a bug in the template library, or it may modify the argument, in which case what you are doing will fail where the function attempts to modify the argument.

Edit: As FredOverflow points out, non-class rvalues are always cv unqualified by the standard 3.10/9. So (2), which works under gcc 4.3, is actually a compiler bug (gcc <4.5, according to FredOverflow).

In this line

function2(function()); 

after function2 returns, the argument that passes to it might have its value change, but since function() returns and it's just assigned to a temporary variable, but what would happen to this temporary variable after it goes out of scope is the problem, that's why the compiler complaints.

To compile the first call, it is necessary to define function2 with T&& parameter - this is rvalue, reference to temporary object. In the second call, v is lvalue reference, it is OK. If your compiler doesn't support rvalue references, the first call may be compiled only with T parameter, without reference.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top