I test il codice nello standard C++ ISO/IEC 14882-03 14.6.1/9 su Xcode 4.1 e Visual Studio 2008. Le uscite di i due compilatori sono entrambi diversi dal risultato previsto dello standard.Il risultato effettivo della risoluzione del nome nel modello di classe è diverso dallo standard C++ 03
Il codice è incollato di seguito.
#include <stdio.h>
#include <iostream>
using namespace std;
void f(char);
template <class T > void g(T t)
{
f(1);
f(T(1));
f(t);
}
void f(int);
void h()
{
g(2);
g('a');
}
void f(int)
{
cout << "f int" << endl;
}
void f(char)
{
cout << "f char" << endl;
}
int main() {
h();
return 0;
}
Come la descrizione dello standard. L'output previsto dovrebbe essere
f char
f int
f int
f char
f char
f char
Creare ed eseguire il codice su Xcode 4.1. L'output è il seguente. Nelle impostazioni di compilazione, ho provato a cambiare il "Compiler per C/C++/Object-C" per essere Apple LLVM Compiler 2.1, Gcc 4.2 e LLVM GCC 4.2. Le uscite sono le stesse.
f char
f char
f char
f char
f char
f char
Costruire ed eseguire il codice su Microsoft Visual Studio 2008. L'output è il seguente.
f int
f int
f int
f int
f char
f char
La descrizione (14.6.1/9) della norma è incollata di seguito.
Se un nome non dipende da un parametro di modello (come definito in 14.6.2), una dichiarazione (o un insieme di dichiarazioni) per tale nome deve essere nel campo di applicazione nel punto in cui il nome appare nel definizione del modello; il nome è legato alla dichiarazione (o dichiarazione) trovata in quel punto e questo legame non è influenzato dalle dichiarazioni che sono visibili nel punto di istanziazione. [Esempio:
void f(char);
template<class T> void g(T t)
{
f(1); // f(char)
f(T(1)); // dependent
f(t); // dependent
dd++; // not dependent
}
void f(int);
double dd;
void h()
{
// error: declaration for dd not found
g(2); // will cause one call of f(char) followed // by two calls of f(int)
g(’a’); // will cause three calls of f(char)
-end esempio]
Il codice è ben formata per compilatori, ma le uscite sono diversi. Sarebbe molto pericoloso portare questo codice su piattaforme diverse.
Qualcuno ha il motivo per cui questi compilatori non seguono lo standard?
Modifica il 10/11/2011
Per http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#197, l'esempio nello standard è sbagliato. Verifica il codice qui sotto su Clang e Gcc.
#include <stdio.h>
#include <iostream>
using namespace std;
void f(char);
template <class T > void g(T t)
{
f(1);
f(T(1));
f(t);
}
enum E{ e };
void f(E);
void h()
{
g(e);
g('a');
}
void f(E)
{
cout << "f E" << endl;
}
void f(char)
{
cout << "f char" << endl;
}
int main() {
h();
return 0;
}
L'uscita come previsto.
f char
f E
f E
f char
f char
f char
Grazie,
Jeffrey
+1 per la prima grande domanda –
È interessante notare che Clang 2.9 sembra avere lo stesso problema di gcc. –