Domanda

Durante la lettura di un'altra domanda, mi è venuto un problema con l'ordinamento parziale, che ho tagliato a il seguente test-case

template<typename T>
struct Const { typedef void type; };

template<typename T>
void f(T, typename Const<T>::type*) { cout << "Const"; } // T1

template<typename T>
void f(T, void*) { cout << "void*"; } // T2

int main() {
  // GCC chokes on f(0, 0) (not being able to match against T1)
  void *p = 0;
  f(0, p);
}

Per entrambi la funzione di modelli, il tipo di funzione della specializzazione che entra la risoluzione dell'overload è void(int, void*).Ma ordinamento parziale (secondo comeau e GCC) ora dice che il secondo modello è più specializzata.Ma perché?

Lasciatemi passare ordinamento parziale e vedi dove ho delle domande.Può Q un unico fatto tipo utilizzato per la determinazione di ordinamento parziale secondo 14.5.5.2.

  • Trasformato parametro-list per la T1 (Q inserita): (Q, typename Const<Q>::type*).I tipi di argomenti sono AT = (Q, void*)
  • Trasformato parametro-list per la T2 (Q inserita): BT = (Q, void*), che sono anche i tipi di argomenti.
  • Non trasformato parametro-list per la T1: (T, typename Const<T>::type*)
  • Non trasformato parametro-list per la T2: (T, void*)

Dal C++03 sotto-specifica di questo, ho utilizzato l'intenzione che ho letto in diversi difetto di report.Sopra trasformata lista di parametri per T1 (chiamato AT da me) è utilizzato come argomento di lista per 14.8.2.1 "Desumere argomenti di template da una chiamata di funzione".

14.8.2.1 non è necessario trasformare AT o BT di per sé più (come, rimozione di riferimento declarators, ecc), e va dritto al 14.8.2.4, che in modo indipendente per ogni A / P coppia fa la deduzione del tipo:

  • AT contro T2: { (Q, T), (void*, void*) }. T è il solo parametro del modello qui, e troverà che T deve essere Q.Tipo di detrazione riesce banalmente per AT contro T2.

  • BT contro T1: { (Q, T), (void*, typename Const<T>::type*) }.Si noterà che T è Q, anche qui. typename Const<T>::type* è un non-dedotta contesto, e in modo da non essere utilizzata per dedurre nulla.


Ecco la mia prima domanda:Sarà questo, ora, utilizzare il valore di T dedotta per la prima parametro?Se la risposta è no, allora il primo modello è più specializzata.Questo non può essere il caso, perché sia GCC e Comeau dire che il secondo modello è più specializzata, e non credo che si sbagliano.Così non ci assumiamo "sì", e inserire void* in T.Il paragrafo (14.8.2.4 dice "La detrazione è effettuata in maniera indipendente per ogni coppia e i risultati vengono poi combinati" e anche "In certi contesti, tuttavia, il valore non partecipa tipo di deduzione, ma utilizza invece i valori del modello di argomenti che sono stati dedotti altrove o esplicitamente specificato." Questo suona come "sì" troppo.

La detrazione, quindi, riesce anche, per ogni A / P coppia.Ora, ogni modello è almeno specializzato come le altre, perché la deduzione non contare, inoltre, su qualsiasi conversioni implicite ed è riuscito in entrambe le direzioni.Come risultato, la chiamata dovrebbe essere ambiguo.

Quindi la mia seconda domanda:Ora, perché le implementazioni di dire che il secondo modello è più specializzato?Il punto che mi ha fatto trascurare?


Modifica:Ho provato la specializzazione esplicita e la creazione di istanze, e sia, in recente versione di GCC (4.4) mi dicono che il riferimento alla specializzazione è ambiguo, mentre una vecchia versione di GCC (4.1 non aumento di ambiguità errore.Questo suggerisce che la più recente versione di GCC non coerenti ordinamento parziale per la funzione dei modelli.

template<typename T>
struct Const { typedef void type; };

template<typename T>
void f(T, typename Const<T>::type*) { cout << "Const"; } // T1

template<typename T>
void f(T, void*) { cout << "void*"; } // T2

template<> void f(int, void*) { }
  // main.cpp:11: error: ambiguous template specialization 
  // 'f<>' for 'void f(int, void*)'
È stato utile?

Soluzione

Ecco il mio andare a questo.Sono d'accordo con Charles Bailey errato passo è quello di andare da Const<Q>::Type* per void*

template<typename T>
void f(T, typename Const<T>::type*) { cout << "Const"; } // T1

template<typename T>
void f(T, void*) { cout << "void*"; } // T2

La procedura si desidera prendere sono:

14.5.5.2/2

Due overload, funzione di modelli, se uno è più specializzati rispetto a un altro può essere determinato mediante la trasformazione di ogni singolo modello e utilizzando argomento detrazione (14.8.2) a confronto con gli altri.

14.5.5.2/3-b1

Per ogni tipo di parametro del modello, sintetizzare un tipo unico e sostituire ogni occorrenza di tale parametro nella funzione di un elenco di parametri, o per un modello di conversione di funzione, il tipo di ritorno.

A mio parere, i tipi sono sintetizzati come segue:

(Q, Const<Q>::Type*)    // Q1
(Q, void*)              // Q2

Non vedo alcuna formulazione, che richiede che il secondo sintetizzato parametro di T1 essere void*.Non so di qualsiasi precedente, che in altri contesti sia.Il tipo Const<Q>::Type* è perfettamente valido, tipo il C++ tipo di sistema.

Così ora possiamo eseguire la detrazione seguente procedura:

T2 a T1

Cerchiamo di dedurre i parametri del modello per T1, quindi abbiamo:

  • Parametro 1: T si deduce di essere Q
  • Parametro 2:Nondeduced contesto

Anche se il parametro 2 è un non dedotta contesto, la detrazione è ancora riusciti perché abbiamo un rapporto T.

T1 a T2

Dedurre i parametri del modello per T2 abbiamo:

  • Parametro 1: T si deduce di essere Q
  • Parametro 2: void* non corrisponde Const<Q>::Type* così detrazione fallimento.

IMHO, qui è dove la standard ci permette.Il parametro non è dipendente, quindi non è chiaro che cosa dovrebbe accadere, tuttavia, la mia esperienza (sulla base di un strizzò gli occhi di lettura di 14.8.2.1/3) è che, anche qualora il tipo di parametro P non è dipendente, quindi l'argomento di tipo A devono corrispondere.

La sintetizzato gli argomenti di T1 può essere utilizzato per specializzarsi T2, ma non viceversa.T2 è quindi più specializzati rispetto a T1 e così è la funzione migliore.


AGGIORNAMENTO 1:

Solo per coprire l'poing circa Const<Q>::type essere vuoto.Si consideri il seguente esempio:

template<typename T>
struct Const;

template<typename T>
void f(T, typename Const<T>::type*) // T1
{ typedef typename T::TYPE1 TYPE; }

template<typename T>
void f(T, void*)                    // T2
{ typedef typename T::TYPE2 TYPE ; }

template<>
struct Const <int>
{
  typedef void type;
};

template<>
struct Const <long>
{
  typedef long type;
};

void bar ()
{
  void * p = 0;
  f (0, p);
}

In precedenza, Const<int>::type viene utilizzato quando stiamo effettuando le consuete regole di risoluzione dell'overload, ma non quando si arriva a parziale regole di overloading.Non sarebbe corretto per scegliere un numero arbitrario di specializzazione per Const<Q>::type.Potrebbe non essere intuitivo, ma il compilatore è molto felice di avere un synthasized tipo di forma Const<Q>::type* e per il tipo di detrazione.


AGGIORNA 2

template <typename T, int I>
class Const
{
public:
  typedef typename Const<T, I-1>::type type;
};

template <typename T>
class Const <T, 0>
{
public:
  typedef void type;
};

template<typename T, int I>
void f(T (&)[I], typename Const<T, I>::type*)     // T1
{ typedef typename T::TYPE1 TYPE; }

template<typename T, int I>
void f(T (&)[I], void*)                           // T2
{ typedef typename T::TYPE2 TYPE ; }


void bar ()
{
  int array[10];
  void * p = 0;
  f (array, p);
}

Quando il Const modello di istanza con un po ' di valore I, in modo ricorsivo crea un'istanza di se stessa fino a quando I arriva a 0.Questo è quando il parziale di specializzazione Const<T,0> è selezionata.Se si dispone di un compilatore che sintetizza alcuni di tipo reale per i parametri della funzione, quindi, il valore che il compilatore sceglie per l'indice dell'array?Diciamo 10?Beh, questo sarebbe bene per l'esempio di cui sopra, ma non corrisponde il parziale di specializzazione Const<T, 10 + 1> che, concettualmente, almeno, sarebbe risultato in un numero infinito di ricorsivi ricorrenze del primario.Qualunque sia il valore selezionato è possibile modificare l'fine condizione che il valore di + 1, e quindi avremmo un ciclo infinito nell'ordinamento parziale algoritmo.

Non vedo come l'ordinamento parziale algoritmo possa istanziare correttamente Const per trovare ciò che type è davvero.

Altri suggerimenti

Edit:Dopo aver studiato Clang attuazione (da Doug Gregor), del loro ordinamento parziale algoritmo, sono venuto a d'accordo con il resto dei manifesti originali che l'esempio non e 'inteso' ambigua - anche se la norma non è chiaro come potrebbe essere di circa che cosa dovrebbe accadere in tali situazioni.Ho modificato questo post per indicare rivisto il mio pensiero (per il mio beneficio proprio e di riferimento).In particolare Clang algoritmo chiarito che 'typename Const<T>::type'non è tradotto in 'void' durante l'ordinamento parziale passo e che ogni Una/P coppia si deduce in modo indipendente.

Inizialmente mi sono chiesto perché è stato considerato ambiguo:

        template<class T> void f(T,T*);  // 1

        template<class T> void f(T, int*); // 2

        f(0, (int*)0); // ambiguous

(The above is ambiguous because one cannot deduce f1(U1,U1*) from f2(T,int*), and going the other way, one cannot deduce f2(U2,int*) from f1(T,T*). Neither is more specialized.)

ma il seguito non sarebbe ambiguo:

        template<class T> struct X { typedef int type; };
        template<class T> void f(T, typename X<T>::type*); // 3
        template<class T> void f(T, int*); // 2

(La ragione per cui uno potrebbe aspettarsi di essere ambiguo, se in seguito dovesse accadere:
- f3(U1,X<U1>::type*) -> f3(U1, int*) ==> f2(T,int*) (deduction ok, T=U1)
- f2(U2,int*) ==> f3(T, X<T>::type*) (deduction ok, T=U2 makes X<U2>::type* -> int*)
Se questo fosse vero, non sarebbe più specializzata rispetto agli altri.)

Dopo aver studiato Clang ordinamento parziale algoritmo è chiaro che trattano '3' sopra come se fosse:

template<class T, class S> void f(T, S*); // 4

così deduzione di alcune unici 'U' contro 'typename X::type' avrà successo -

  • f3(U1,X<U1>::type*) is treated as f3(U1, U2*) ==> f2(T,int*) (deduction not ok)
  • f2(U2,int*) ==> f3(T,S* [[X<T>::type*]]) (deduction ok, T=U2, S=int)

E cosi '2' è chiaramente più specializzati rispetto a '3'.

Trasformato parametri-lista per T1 (Q inserita):(Q, typename Const::tipo*).I tipi di gli argomenti sono A = (Q, void*)

Mi chiedo se è corretto semplificazione.Quando si sintetizzano il tipo Q, si può evocare una specializzazione per Const ai fini della determinazione dell'ordinamento del modello specliazation?

template <>
struct Const<Q> { typedef int type; }

Questo implica che T2 non è, almeno specializzato come T1 perché un void* parametro non corrisponde T1's secondo parametro per ogni i parametri del modello.

Edit:Si prega di ignorare questo post Dopo aver studiato risuona algoritmo di ordinamento parziale, come è implementato da Doug Gregor (anche se solo parzialmente implementato come di questa scrittura - sembra che la logica pertinente all'OP la domanda è implementato in maniera sufficientemente) - sembra come se si considera il undeduced contesto come un altro parametro del modello.Il che suggerisce che il sovraccarico con l'esplicito void* argomento dovrebbe essere la più specializzata versione e non ci devono essere ambiguità.Come al solito Comeau è corretto.Ora, per quanto riguarda la formulazione della norma, che definisce chiaramente questo comportamento - che è un'altra questione ...

Dato che questo post è stato pubblicato anche su comp.lang.c++.moderati, e sembra essere la causa di un po ' di confusione c'troppo - ho pensato di postare la mia risposta a quel gruppo anche qui - visto che la discussione è ovviamente rilevante per la domanda qui.

On Jul 25, 1:11 pm, Bart van Ingen Schenau <b...@ingen.ddns.info> wrote:

You are going one step too fast here. How do you know (and would the compiler know) that there is no specialisation of Const<Q> such that Const<Q>::type != void?

As far as I can see, the compiler would transform the parameter-list of A to: AT=(Q, <unknown>*). To call B with these parameters requires an implicit conversion (<unknown>* to void*) and therefore A is less specialised than B.

Credo che questo non è corretto.Quando si verifica che la funzione è più specializzati (durante parziale-dell'ordine), il compilatore trasforma il i parametri-lista di (Q, void*) - cioèeffettivamente crea pertinenti modello (il migliore abbinamento) e guarda dentro per il valore di 'tipo' - in questo caso, in base sul primario del modello, sarà void*.

Per quanto riguarda il punto riguardante la specializzazione parziale - durante il controllo per che modello è più specializzata rispetto agli altri, l'unico tipo che può essere utilizzato è l'unico generato tipo - se non ci sono altre specializzazioni presso il punto di della creazione di un'istanza di dichiarazione (quando la risoluzione dell'overload è stato fatto) devono essere presi in considerazione.Se aggiungerli in un secondo momento, e che dovrebbero avere selezionato si saranno violazione ODR (secondo 14.7.4.1)

Il parziale/esplicito specializzazioni riceverà anche considertaion durante la formazione del candidato set, ma questa volta utilizzando i tipi di argomenti attuali per la funzione.Se la migliore corrispondenza parziale di specializzazione (X) si traduce in un tipo di funzione che ha una migliore conversione implicita sequenza per alcuni parametro, quindi abbiamo mai parziale fase di ordine, e che "meglio" funzione di ottenere selezionato (prima di effettuare il parziale fase di ordine)

Ecco un esempio con commenti su ciò che sta succedendo in varie fasi:

    template<class T, bool=true> struct X;  // Primary

    template<class T> struct X<T,true> { typedef T type; };  // A
    template<> struct X<int*,true> { typedef void* type; };  // B


    template<class T> void f(T,typename X<T>::type); //1
    template<class T> void f(T*,void*); //2


    int main()
    {
      void* pv;
      int* pi;


      f(pi,pi);   
      // two candidate functions: f1<int*>(int*,void*),  f2<int>(int*,void*)
      // Note: specialization 'B' used to arrive at void* in f1
      // neither has a better ICS than the other, so lets partially order
      // transformed f1 is f1<U1>(U1,X<U1,true>::type) --> f1<U1>(U1,U1) 
      //       (template 'A' used to get the second U1)
      // obviously deduction will fail (U1,U1) -> (T*,void*)
      // and also fails the other way (U2*, void*) -> (T,X<T>::type)
      // can not partially order them - so ambiguity 




      f(pv,pv);  
      // two candidate functions: f1<void*>(void*,void*), f2<void>(void*,void*)
      // Note: specialization 'A' used to arrive at second void* in f1
      // neither has a better ICS than the other, so lets partially order
      // transformed f1 is f1<U1>(U1,X<U1>::type) --> f1<U1>(U1,U1) 
      //       (template 'A' used to get the second U1)
      // obviously deduction will fail (U1,U1) -> (T*,void*)
      // and also fails the other way (U2*, void*) -> (T,X<T>::type)
      // can not partially order them - so ambiguity again             

    }

Vale anche la pena di ricordare che se il primario modello non ha una definizione - quindi SFINAE opera durante la parziale fase di ordine, né può essere desunta da altri, e l'ambiguità che dovrebbe essere il risultato.

Anche se si aggiunge un altro modello che porterebbe ad un'altra partita se il punto di instantation di queste funzioni è spostato altrove in unità di traduzione è in palese violazione ODR.

On Jul 25, 1:11 pm, Bart van Ingen Schenau <b...@ingen.ddns.info> wrote:

La prima, quella più specializzata, significa che questi sono meno tipi di tale modello può essere selezionato da sovraccarico di risoluzione.Usando questo, le regole per l'ordinamento parziale può essere così riassunta:Tenta di trovare un tipo per una tale può essere chiamato, ma B non è, o sovraccarico risoluzione preferisce chiamare A.Se questo tipo di può essere trovato, allora B è più specializzata di A.

Nessun argomento qui.Ma in base alle regole come sono attualmente, por esempio, deve essere ambiguo.


Infine, qui sono esplicito, inequivocabile risposte alle due questioni specifiche sollevate dai litb:

1) questo ora uso il valore di T dedotta per la prima parametro?
Sì, naturalmente, è, è questo modello argomento detrazione il 'link' essere mantenuta.

2) Ora, perché le implementazioni di dire che la seconda è più specializzata, invece?
Perché è sbagliato ;)

Spero che questo pone il problema del riposo - per Favore fatemi sapere se c'è qualcosa che non è ancora chiaro :)

Edit:litb sollevato un buon punto nel suo commento - forse affermando che il primo modello sarà sempre utilizzato per la creazione di istanze con l'unico generato tipo è troppo forte una dichiarazione.
Ci sono casi in cui il principale modello non verrà chiamato.
Quello che sto ottenendo è che quando ordinamento parziale è in corso, alcuni univoco generato è di tipo utilizzato per adattare al meglio la specializzazione.Hai ragione, non deve essere il principale modello.Ho modificato le lingue di cui sopra per farlo.Egli ha anche sollevato un problema relativo alla definizione di un migliore abbinamento modello, dopo il punto di instantation.Che sarà una violazione di ODR, secondo la sezione sul punto di istanziazione.


Lo standard dice che una volta A/P coppie sono creati utilizzando le regole di trasformazione, come descritto in temp.func.ordine) sono dedotte contro l'altro utilizzando il modello argomento detrazione (temp.detrarre)- e che la sezione gestisce il caso di non dedurre contesti, creando il modello e il suo tipo annidato, attivazione di punti di istanze.Temp.punto di sezione gestisce l'ODR violazioni (il significato di ordinamento parziale non dovrebbe cambiare, a prescindere dai punti di instantation all'interno di una unità di traduzione).Ancora non sono sicuro di dove la confusione sono provenienti da?– Faisal Vali 1 ora fa [cancellare questo commento]

litb:"Si noti che il passaggio che mette di Q Const::tipo a costruire gli argomenti non contemplati esplicitamente dal SFINAE regola.Il SFINAE regole di lavoro con argomento detrazione, mettere i paragrafi che mettere Q il modello di funzione di funzione di un elenco di parametri sono a 14.5.5.2.'

Il SFINAE regole devono essere utilizzati qui - come potrebbe non essere?Sento sufficientemente implicita - non nego che potrebbe essere più chiara, e mentre incoraggio il comitato per chiarire io non credo che ha bisogno di essere chiarita per interpretare il tuo esempio sufficientemente.

Permettetemi di fornire un modo per collegarli.Da (14.8.2):"Quando un esplicito modello di elenco di argomenti è specificato, il modello argomenti devono essere compatibili con il modello di un elenco di parametri e deve trasformarsi in un valido tipo di funzione come descritto di seguito;altrimenti la deduzione del tipo non riesce"

Da (14.5.5.2/3) "La trasformazione utilizzato è:— Per ogni tipo di parametro del modello, sintetizzare un tipo unico e sostituire ogni occorrenza di tale parametro nella funzione di un elenco di parametri, o per un modello di conversione di funzione, il tipo di ritorno."

Nella mia mente, la citazione precedente implica che una volta che si "crea" unico generato i tipi per ogni parametro di modello, la dichiarazione di funzione deve essere implicity creata un'istanza di in modo esplicito fornendo i tipi unici come argomenti di modello per il nostro modello di funzione.Se questo si traduce in un non valido tipo di funzione, quindi non solo la trasformazione, ma soprattutto il successivo modello argomento detrazione necessario parzialmente ordine la funzione ha esito negativo.

Da (14.5.5.2/4) "Utilizzando la trasformata della funzione di un elenco di parametri, eseguire argomento detrazione contro gli altri template di funzione.La trasformata modello è di almeno specializzato come le altre se, e solo se, la detrazione ha esito positivo e il dedotto i tipi di parametro sono una corrispondenza esatta (quindi la detrazione non si basa su conversioni implicite)."

Se la trasformata della funzione di un elenco di parametri comporta la sostituzione di fallimento, poi sappiamo che la detrazione potrebbe non essere riuscito.E dal momento che la detrazione non è riuscita, non è specializzato come l'altro, che è ciò di cui abbiamo bisogno per procedere nell'ordinamento parziale i due.

litb:Io non sono anche sicuro di quello che succede in questo caso: template<typename T> struct A; template<typename T> void f(T, typename A<T>::type); template<typename T> void f(T*, typename A<T>::type); sicuramente, che indended essere un codice valido, ma facendo Un::tipo, avrà esito negativo perché il definizione di un modello di contesto, non è ancora definita" Nota anche che non c'è nessun PDI definito per modello istanze derivanti dal presente tipo di sostituzione durante il tentativo di stabilire un ordinamento (ordinamento parziale non dipende in qualsiasi contesto.È una proprietà statica di funzione di due modelli in questione).Penso che questo sembra un problema di Standard che deve essere risolto.

Ok - mi sembra di vedere dove stiamo vedendo le cose in modo diverso.Se ho capito bene, stai dicendo che come funzionano i modelli di ottenere dichiarato, il compilatore è mantenere una traccia di ordinamento parziale tra di loro, indipendentemente dalla risoluzione dell'overload di aver mai attivato per selezionare tra di loro.Se questo è il modo di interpretarlo, quindi posso capire perché si aspetta che il precedente comportamento che tu descrivi.Ma non credo che lo standard richiede sempre o mandati.

Ora, la norma è chiaro che l'ordinamento parziale agnostico, del tipo che viene utilizzato in una chiamata alla funzione (credo questo è ciò che si fa riferimento quando si descrive come una proprietà statica e contesto indipendente).

La norma è anche chiaro che non si preoccupa solo parziale, dell'ordine (richiama ordinamento parziale) tra la funzione di modelli di durante il processo di risoluzione dell'overload (13.3.3/1) se e solo se è impossibile scegliere la migliore funzione basata su ICS o se uno è un modello e l'altro no.[Ordinamento parziale del modello di classe parziale specializzazioni è una questione a parte e nella mia mente utilizza il contesto rilevante (altre definizioni di modello) che richiede la creazione di un'istanza della classe.]

Quindi, a mio parere, in quanto la meccanica di ordinamento parziale della funzione di modelli viene richiamato quando il sovraccarico viene eseguita la risoluzione, si deve utilizzare una porzione rilevante del contesto (definizioni di modello e specializzazioni) disponibile al punto quando il sovraccarico di risoluzione è stato fatto.

Quindi, in base alla mia interepretation, secondo il tuo esempio, utilizzando il "modello di struttura di Un' di cui sopra, il codice è valido.L'ordinamento parziale non è fatto alla definizione del contesto.Ma se/quando ti capita di invocare la risoluzione dell'overload tra le due funzioni scrivendo una chiamata di f((int*)0,0) - e a quel tempo in cui il compilatore o cerca di assemblare un candidato dichiarazione o parzialmente ordinare (se ottiene per il parziale di ordinazione passo) se un'espressione non valida o tipo di risultati come parte di un tipo di funzione, SFINAE ci aiuta e dice noi che modello di detrazione non riesce (per quanto riguarda ordinamento parziale è interessato, che implica che uno non può essere più specializzati rispetto a gli altri se non si potrebbe anche trasformare il modello).

Ora per quanto riguarda Poi, se si è convinti, come sono, che la trasforma i tipi di funzione sono tenuti a rappresentano implicita istanze utilizzando esplicitamente fornito un modello di elenchi di argomenti (utilizzando in modo univoco generato tipi) quindi i seguenti standard quotazioni sono rilevanti:

14.6.4.1/1 Per una funzione del modello di specializzazione, una funzione membro di un modello di specializzazione, o perfezionamento per un funzione membro o membro statico di una classe modello, se la specializzazione è implicitamente istanziato perché è fatto riferimento dall'interno di un altro modello di specializzazione e il contesto da cui è fatto riferimento dipende da un parametro di modello, il punto di creazione di un'istanza della specializzazione è il punto di istanza della cinta di specializzazione.

La mia interpretazione è che il PDI della trasformazione del tipo di funzione e originale tipo di funzione è il stesso come il PDI per le funzioni create dall'effettiva chiamata di funzione.

litb:Poiché ordinamento parziale è invece solo a property of the syntactic form of parameters (i.e "T*" against "T(*)[N]"), io voto per la modifica dell'specifica (come "se Q appare in un nidificati nome identificatore del un qualificato-id denominazione di un tipo, poi il tipo di nome è "Q") O dicendo che il tipo di nome è un altro tipo unico. This means that in template<typename T> void f(T, typename Const<T>::type*); the argument list is (Q, R*), for example. Same for template<typename T> void f(T*, typename ConstI<sizeof(T)>::type); the arg lisst would be (Q*, R). A similar rule would be needed for non-type parameters, of course. Avrei dovuto pensarci e di fare in alcuni casi di test per vedere se questo sarebbe resa naturale ordinamenti, però.

Aah - ora stai suggerendo una possibile soluzione che risolve l'ambiguità a favore di ciò che tutti intuitivo aspettarsi - questo è un problema a parte, e mentre mi piace la direzione che si sta muovendo in, come te, anch'io vorrei mettere qualche pensiero in esso, prima di proclamare la sua lavorabilità.

Grazie per continuare la discussione.Mi auguro QUINDI che non solo limite di immissione di commenti.

Dal momento che è possibile modificare i miei messaggi, non esitate a rispondere entro il post se che è più facile.

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