[explications très intéressantes de l'« Argument dependent name lookup »]
// foo.C
#include "sum.h"
namespace N {
struct foo {
// ...
};
foo add(foo, foo) { ... } // #1
}
int main()
{
N::foo foos[930];
N::foo s = sum(foos, 903); // #2
}
Dans #2, l'instantiation de sum<> va trouver le add() en ligne #1.
Cependant, si comme certains semblent l'adopter en règle, le add dans
N:: a été déclaré static parce qu'elle ne sert que dans foo.C,
même si
elle est trouvée par ADL, la seconde phase de résolution des noms va
l'ignorer, parce qu'elle a un linkage interne. Ce qui provoquera une
erreur -- même si la add() se trouve dans la même unité de traduction
que son utilisation.
[explications très intéressantes de l'« Argument dependent name lookup »]
// foo.C
#include "sum.h"
namespace N {
struct foo {
// ...
};
foo add(foo, foo) { ... } // #1
}
int main()
{
N::foo foos[930];
N::foo s = sum(foos, 903); // #2
}
Dans #2, l'instantiation de sum<> va trouver le add() en ligne #1.
Cependant, si comme certains semblent l'adopter en règle, le add dans
N:: a été déclaré static parce qu'elle ne sert que dans foo.C,
même si
elle est trouvée par ADL, la seconde phase de résolution des noms va
l'ignorer, parce qu'elle a un linkage interne. Ce qui provoquera une
erreur -- même si la add() se trouve dans la même unité de traduction
que son utilisation.
[explications très intéressantes de l'« Argument dependent name lookup »]
// foo.C
#include "sum.h"
namespace N {
struct foo {
// ...
};
foo add(foo, foo) { ... } // #1
}
int main()
{
N::foo foos[930];
N::foo s = sum(foos, 903); // #2
}
Dans #2, l'instantiation de sum<> va trouver le add() en ligne #1.
Cependant, si comme certains semblent l'adopter en règle, le add dans
N:: a été déclaré static parce qu'elle ne sert que dans foo.C,
même si
elle est trouvée par ADL, la seconde phase de résolution des noms va
l'ignorer, parce qu'elle a un linkage interne. Ce qui provoquera une
erreur -- même si la add() se trouve dans la même unité de traduction
que son utilisation.
Pendant que certaines personnes s'acharnaient à
donner à static, son seul sens qu'il aurait dû avoir, d'autres
personnes ont trouvé l'opportunité de faire en sorte qu'il n'affecte
plus seulement le linkage mais aussi name lookup
Pendant que certaines personnes s'acharnaient à
donner à static, son seul sens qu'il aurait dû avoir, d'autres
personnes ont trouvé l'opportunité de faire en sorte qu'il n'affecte
plus seulement le linkage mais aussi name lookup
Pendant que certaines personnes s'acharnaient à
donner à static, son seul sens qu'il aurait dû avoir, d'autres
personnes ont trouvé l'opportunité de faire en sorte qu'il n'affecte
plus seulement le linkage mais aussi name lookup
14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules (3.4.1,
3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had the
lookup within the associated namespaces considered all the function
declarations with external linkage introduced in those namespaces in all
translation units, not just considering those declarations found in
the template definition and template instantiation contexts, then
the program has undefined behavior.
14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules (3.4.1,
3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had the
lookup within the associated namespaces considered all the function
declarations with external linkage introduced in those namespaces in all
translation units, not just considering those declarations found in
the template definition and template instantiation contexts, then
the program has undefined behavior.
14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules (3.4.1,
3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had the
lookup within the associated namespaces considered all the function
declarations with external linkage introduced in those namespaces in all
translation units, not just considering those declarations found in
the template definition and template instantiation contexts, then
the program has undefined behavior.
Gabriel Dos Reis wrote in message
news:...14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules (3.4.1,
3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had the
lookup within the associated namespaces considered all the function
declarations with external linkage introduced in those namespaces in all
translation units, not just considering those declarations found in
the template definition and template instantiation contexts, then
the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
Gabriel Dos Reis <gdr@integrable-solutions.net> wrote in message
news:<m3vfikrnr0.fsf@uniton.integrable-solutions.net>...
14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules (3.4.1,
3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had the
lookup within the associated namespaces considered all the function
declarations with external linkage introduced in those namespaces in all
translation units, not just considering those declarations found in
the template definition and template instantiation contexts, then
the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
Gabriel Dos Reis wrote in message
news:...14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules (3.4.1,
3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had the
lookup within the associated namespaces considered all the function
declarations with external linkage introduced in those namespaces in all
translation units, not just considering those declarations found in
the template definition and template instantiation contexts, then
the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
writes:
[ Le contexte était l'impact de « static » pour les fonctions
non-membres sur la recherche de noms dans les templates, définitions
ou instantiations. ]
| Gabriel Dos Reis wrote in message
| news:...
| > 14.6.4.2/1
| > For a function call that depends on a template parameter, if the
| > function name is an unqualified-id but not a template-id, the
| > candidate functions are found using the usual lookup rules (3.4.1,
| > 3.4.2) except that:
| > -- For the part of the lookup using unqualified name lookup (3.4.1),
| > only function declarations with external linkage from the
| > template definition context are found.
| > -- For the part of the lookup using associated namespaces (3.4.2),
| > only function declarations with external linkage found in either
| > the template definition context or the template instantiation
| > context are found.
| > If the call would be ill-formed or would find a better match had
| > the lookup within the associated namespaces considered all the
| > function declarations with external linkage introduced in those
| > namespaces in all translation units, not just considering those
| > declarations found in the template definition and template
| > instantiation contexts, then the program has undefined behavior.
| Je ne sais pas si j'ai bien compris. Considérons le programme suivant :
| #include <ostream>
| #include <iostream>
| template< typename T >
| void
| dump( char const* name, T const& value )
| {
| std::cout << name << " = " << value << 'n' ;
| }
| struct C
| {
| int val ;
| C( int init ) : val( init ) {}
| } ;
| std::ostream&
| operator<<( std::ostream& out, C value )
| {
| out << value.val ;
| return out ;
| }
| int
| main()
| {
| C c( 42 ) ;
| dump( "c", c ) ;
| return 0 ;
| }
| Qu'est-ce que ce passage signifie à son égard ?
Il n'est pas applicable parce que aucune de tes fonctions avec un nom
dépendant n'a un linkage interne.
| Qu'il est illégal (parce que la recherche non-qualifiée se fait
| uniquement dans le contexte de la définition du template, et ne
| trouve pas l'opérateur << qui convient) ?
Non, il est bien valide parce que les trois operator<< n'ont pas de
linkage internes et la recherche de noms (les deux formes) les
trouvera.
| Qu'il a un comportement indéfini (à cause du dernier paragraphe) ?
| Ou est-ce que je n'ai rien compris, comme d'habitude ? (Le code
| marche comme je m'y attendrais de façon naïve avec g++ 3.3.1.
Je crois que tu n'as pas tenu cmpte du contexte de la discussion :
Pendant que certaines personnes s'acharnaient à donner à static,
son seul sens qu'il aurait dû avoir, d'autres personnes ont
trouvé l'opportunité de faire en sorte qu'il n'affecte plus
seulement le linkage mais aussi name lookup
| Mais le fait que le code marche ne prouve pas l'absense du
| comportement indéfini. Et je ne crois pas que g++ 3.3.1 soit 100%
| conforme non plus en ce qui concerne la recherche des noms dans les
| templates.)
mais dans ce cas précis, il fait la bonne chose :-)
kanze@gabi-soft.fr writes:
[ Le contexte était l'impact de « static » pour les fonctions
non-membres sur la recherche de noms dans les templates, définitions
ou instantiations. ]
| Gabriel Dos Reis <gdr@integrable-solutions.net> wrote in message
| news:<m3vfikrnr0.fsf@uniton.integrable-solutions.net>...
| > 14.6.4.2/1
| > For a function call that depends on a template parameter, if the
| > function name is an unqualified-id but not a template-id, the
| > candidate functions are found using the usual lookup rules (3.4.1,
| > 3.4.2) except that:
| > -- For the part of the lookup using unqualified name lookup (3.4.1),
| > only function declarations with external linkage from the
| > template definition context are found.
| > -- For the part of the lookup using associated namespaces (3.4.2),
| > only function declarations with external linkage found in either
| > the template definition context or the template instantiation
| > context are found.
| > If the call would be ill-formed or would find a better match had
| > the lookup within the associated namespaces considered all the
| > function declarations with external linkage introduced in those
| > namespaces in all translation units, not just considering those
| > declarations found in the template definition and template
| > instantiation contexts, then the program has undefined behavior.
| Je ne sais pas si j'ai bien compris. Considérons le programme suivant :
| #include <ostream>
| #include <iostream>
| template< typename T >
| void
| dump( char const* name, T const& value )
| {
| std::cout << name << " = " << value << 'n' ;
| }
| struct C
| {
| int val ;
| C( int init ) : val( init ) {}
| } ;
| std::ostream&
| operator<<( std::ostream& out, C value )
| {
| out << value.val ;
| return out ;
| }
| int
| main()
| {
| C c( 42 ) ;
| dump( "c", c ) ;
| return 0 ;
| }
| Qu'est-ce que ce passage signifie à son égard ?
Il n'est pas applicable parce que aucune de tes fonctions avec un nom
dépendant n'a un linkage interne.
| Qu'il est illégal (parce que la recherche non-qualifiée se fait
| uniquement dans le contexte de la définition du template, et ne
| trouve pas l'opérateur << qui convient) ?
Non, il est bien valide parce que les trois operator<< n'ont pas de
linkage internes et la recherche de noms (les deux formes) les
trouvera.
| Qu'il a un comportement indéfini (à cause du dernier paragraphe) ?
| Ou est-ce que je n'ai rien compris, comme d'habitude ? (Le code
| marche comme je m'y attendrais de façon naïve avec g++ 3.3.1.
Je crois que tu n'as pas tenu cmpte du contexte de la discussion :
Pendant que certaines personnes s'acharnaient à donner à static,
son seul sens qu'il aurait dû avoir, d'autres personnes ont
trouvé l'opportunité de faire en sorte qu'il n'affecte plus
seulement le linkage mais aussi name lookup
| Mais le fait que le code marche ne prouve pas l'absense du
| comportement indéfini. Et je ne crois pas que g++ 3.3.1 soit 100%
| conforme non plus en ce qui concerne la recherche des noms dans les
| templates.)
mais dans ce cas précis, il fait la bonne chose :-)
writes:
[ Le contexte était l'impact de « static » pour les fonctions
non-membres sur la recherche de noms dans les templates, définitions
ou instantiations. ]
| Gabriel Dos Reis wrote in message
| news:...
| > 14.6.4.2/1
| > For a function call that depends on a template parameter, if the
| > function name is an unqualified-id but not a template-id, the
| > candidate functions are found using the usual lookup rules (3.4.1,
| > 3.4.2) except that:
| > -- For the part of the lookup using unqualified name lookup (3.4.1),
| > only function declarations with external linkage from the
| > template definition context are found.
| > -- For the part of the lookup using associated namespaces (3.4.2),
| > only function declarations with external linkage found in either
| > the template definition context or the template instantiation
| > context are found.
| > If the call would be ill-formed or would find a better match had
| > the lookup within the associated namespaces considered all the
| > function declarations with external linkage introduced in those
| > namespaces in all translation units, not just considering those
| > declarations found in the template definition and template
| > instantiation contexts, then the program has undefined behavior.
| Je ne sais pas si j'ai bien compris. Considérons le programme suivant :
| #include <ostream>
| #include <iostream>
| template< typename T >
| void
| dump( char const* name, T const& value )
| {
| std::cout << name << " = " << value << 'n' ;
| }
| struct C
| {
| int val ;
| C( int init ) : val( init ) {}
| } ;
| std::ostream&
| operator<<( std::ostream& out, C value )
| {
| out << value.val ;
| return out ;
| }
| int
| main()
| {
| C c( 42 ) ;
| dump( "c", c ) ;
| return 0 ;
| }
| Qu'est-ce que ce passage signifie à son égard ?
Il n'est pas applicable parce que aucune de tes fonctions avec un nom
dépendant n'a un linkage interne.
| Qu'il est illégal (parce que la recherche non-qualifiée se fait
| uniquement dans le contexte de la définition du template, et ne
| trouve pas l'opérateur << qui convient) ?
Non, il est bien valide parce que les trois operator<< n'ont pas de
linkage internes et la recherche de noms (les deux formes) les
trouvera.
| Qu'il a un comportement indéfini (à cause du dernier paragraphe) ?
| Ou est-ce que je n'ai rien compris, comme d'habitude ? (Le code
| marche comme je m'y attendrais de façon naïve avec g++ 3.3.1.
Je crois que tu n'as pas tenu cmpte du contexte de la discussion :
Pendant que certaines personnes s'acharnaient à donner à static,
son seul sens qu'il aurait dû avoir, d'autres personnes ont
trouvé l'opportunité de faire en sorte qu'il n'affecte plus
seulement le linkage mais aussi name lookup
| Mais le fait que le code marche ne prouve pas l'absense du
| comportement indéfini. Et je ne crois pas que g++ 3.3.1 soit 100%
| conforme non plus en ce qui concerne la recherche des noms dans les
| templates.)
mais dans ce cas précis, il fait la bonne chose :-)
writes:Gabriel Dos Reis wrote in message
news:...14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules
(3.4.1, 3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had
the lookup within the associated namespaces considered all the
function declarations with external linkage introduced in those
namespaces in all translation units, not just considering those
declarations found in the template definition and template
instantiation contexts, then the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme
suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
A mon avis, on trouve l'operator<< (qui a un linkage externe) par le
recherche utilisant les namespace associes dans le contexte de
l'instanciation (le dump dans main). Comme il n'y a qu'une unite de
traduction et que le contexte d'instanciation comporte toutes les
declarations de linkage externe de celle-ci, le dernier paragraphe
n'est pas a considerer.
kanze@gabi-soft.fr writes:
Gabriel Dos Reis <gdr@integrable-solutions.net> wrote in message
news:<m3vfikrnr0.fsf@uniton.integrable-solutions.net>...
14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules
(3.4.1, 3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had
the lookup within the associated namespaces considered all the
function declarations with external linkage introduced in those
namespaces in all translation units, not just considering those
declarations found in the template definition and template
instantiation contexts, then the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme
suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
A mon avis, on trouve l'operator<< (qui a un linkage externe) par le
recherche utilisant les namespace associes dans le contexte de
l'instanciation (le dump dans main). Comme il n'y a qu'une unite de
traduction et que le contexte d'instanciation comporte toutes les
declarations de linkage externe de celle-ci, le dernier paragraphe
n'est pas a considerer.
writes:Gabriel Dos Reis wrote in message
news:...14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules
(3.4.1, 3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had
the lookup within the associated namespaces considered all the
function declarations with external linkage introduced in those
namespaces in all translation units, not just considering those
declarations found in the template definition and template
instantiation contexts, then the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme
suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
A mon avis, on trouve l'operator<< (qui a un linkage externe) par le
recherche utilisant les namespace associes dans le contexte de
l'instanciation (le dump dans main). Comme il n'y a qu'une unite de
traduction et que le contexte d'instanciation comporte toutes les
declarations de linkage externe de celle-ci, le dernier paragraphe
n'est pas a considerer.
Jean-Marc Bourguet wrote in message
news:...writes:Gabriel Dos Reis wrote in message
news:...14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules
(3.4.1, 3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had
the lookup within the associated namespaces considered all the
function declarations with external linkage introduced in those
namespaces in all translation units, not just considering those
declarations found in the template definition and template
instantiation contexts, then the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme
suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
A mon avis, on trouve l'operator<< (qui a un linkage externe) par le
recherche utilisant les namespace associes dans le contexte de
l'instanciation (le dump dans main). Comme il n'y a qu'une unite de
traduction et que le contexte d'instanciation comporte toutes les
declarations de linkage externe de celle-ci, le dernier paragraphe
n'est pas a considerer.
C'est ce que je commence à croire moi-même. C'est que selon ma premier
analyse, C ne se trouvait pas dans un namespace ; c'est donc que la
recherche dépendante aux paramètres ne pourrait pas le retrouver. Mais
tout compte fait, je crois que la norme considère le namespace global
comme n'importe quel autre namespace -- l'absense d'un namespace, c'est
un namespace.
C'est raisonable, mais dans ce cas-là, pourquoi ne pas y mettre les
types de base aussi ?
Mais je deviens de plus en plus confus. Ce qui m'a mis la puce à
l'oreille, c'est que je me suis rappelé d'un cas où on avait surchargé
l'opérateur << pour un std::vector< double >, et que le compilateur n'a
pas trouver ce surcharge quand on utiliser un std::ostream_iterator. (Je
crois que c'était le cas. Je n'ai plus le code exact sous la main.) OK,
je comprends. Le problème, c'est que double, c'est un type de base, qui
n'est dans aucun namespace, même pas le namespace global. Sauf que je
viens d'essayer avec mon exemple ci-dessus, en remplaçant C par
std::vector<double>, et ça compile aussi. Alors, pourquoi ça compile
avec mon template dump, et non avec ostream_iterator ?
Une question subsidiaire serait : est-ce que le tout n'est pas un
peu trop compliqué ? Au point, même, que si on se sert des
templates, on ne peut plus savoir si son code est correct ou non.
Jean-Marc Bourguet <jm@bourguet.org> wrote in message
news:<pxbd64rzjl1.fsf@news.bourguet.org>...
kanze@gabi-soft.fr writes:
Gabriel Dos Reis <gdr@integrable-solutions.net> wrote in message
news:<m3vfikrnr0.fsf@uniton.integrable-solutions.net>...
14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules
(3.4.1, 3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had
the lookup within the associated namespaces considered all the
function declarations with external linkage introduced in those
namespaces in all translation units, not just considering those
declarations found in the template definition and template
instantiation contexts, then the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme
suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
A mon avis, on trouve l'operator<< (qui a un linkage externe) par le
recherche utilisant les namespace associes dans le contexte de
l'instanciation (le dump dans main). Comme il n'y a qu'une unite de
traduction et que le contexte d'instanciation comporte toutes les
declarations de linkage externe de celle-ci, le dernier paragraphe
n'est pas a considerer.
C'est ce que je commence à croire moi-même. C'est que selon ma premier
analyse, C ne se trouvait pas dans un namespace ; c'est donc que la
recherche dépendante aux paramètres ne pourrait pas le retrouver. Mais
tout compte fait, je crois que la norme considère le namespace global
comme n'importe quel autre namespace -- l'absense d'un namespace, c'est
un namespace.
C'est raisonable, mais dans ce cas-là, pourquoi ne pas y mettre les
types de base aussi ?
Mais je deviens de plus en plus confus. Ce qui m'a mis la puce à
l'oreille, c'est que je me suis rappelé d'un cas où on avait surchargé
l'opérateur << pour un std::vector< double >, et que le compilateur n'a
pas trouver ce surcharge quand on utiliser un std::ostream_iterator. (Je
crois que c'était le cas. Je n'ai plus le code exact sous la main.) OK,
je comprends. Le problème, c'est que double, c'est un type de base, qui
n'est dans aucun namespace, même pas le namespace global. Sauf que je
viens d'essayer avec mon exemple ci-dessus, en remplaçant C par
std::vector<double>, et ça compile aussi. Alors, pourquoi ça compile
avec mon template dump, et non avec ostream_iterator ?
Une question subsidiaire serait : est-ce que le tout n'est pas un
peu trop compliqué ? Au point, même, que si on se sert des
templates, on ne peut plus savoir si son code est correct ou non.
Jean-Marc Bourguet wrote in message
news:...writes:Gabriel Dos Reis wrote in message
news:...14.6.4.2/1
For a function call that depends on a template parameter, if the
function name is an unqualified-id but not a template-id, the
candidate functions are found using the usual lookup rules
(3.4.1, 3.4.2) except that:
-- For the part of the lookup using unqualified name lookup (3.4.1),
only function declarations with external linkage from the
template definition context are found.
-- For the part of the lookup using associated namespaces (3.4.2),
only function declarations with external linkage found in either
the template definition context or the template instantiation
context are found.
If the call would be ill-formed or would find a better match had
the lookup within the associated namespaces considered all the
function declarations with external linkage introduced in those
namespaces in all translation units, not just considering those
declarations found in the template definition and template
instantiation contexts, then the program has undefined behavior.
Je ne sais pas si j'ai bien compris. Considérons le programme
suivant :
#include <ostream>
#include <iostream>
template< typename T >
void
dump( char const* name, T const& value )
{
std::cout << name << " = " << value << 'n' ;
}
struct C
{
int val ;
C( int init ) : val( init ) {}
} ;
std::ostream&
operator<<( std::ostream& out, C value )
{
out << value.val ;
return out ;
}
int
main()
{
C c( 42 ) ;
dump( "c", c ) ;
return 0 ;
}
Qu'est-ce que ce passage signifie à son égard ?
A mon avis, on trouve l'operator<< (qui a un linkage externe) par le
recherche utilisant les namespace associes dans le contexte de
l'instanciation (le dump dans main). Comme il n'y a qu'une unite de
traduction et que le contexte d'instanciation comporte toutes les
declarations de linkage externe de celle-ci, le dernier paragraphe
n'est pas a considerer.
C'est ce que je commence à croire moi-même. C'est que selon ma premier
analyse, C ne se trouvait pas dans un namespace ; c'est donc que la
recherche dépendante aux paramètres ne pourrait pas le retrouver. Mais
tout compte fait, je crois que la norme considère le namespace global
comme n'importe quel autre namespace -- l'absense d'un namespace, c'est
un namespace.
C'est raisonable, mais dans ce cas-là, pourquoi ne pas y mettre les
types de base aussi ?
Mais je deviens de plus en plus confus. Ce qui m'a mis la puce à
l'oreille, c'est que je me suis rappelé d'un cas où on avait surchargé
l'opérateur << pour un std::vector< double >, et que le compilateur n'a
pas trouver ce surcharge quand on utiliser un std::ostream_iterator. (Je
crois que c'était le cas. Je n'ai plus le code exact sous la main.) OK,
je comprends. Le problème, c'est que double, c'est un type de base, qui
n'est dans aucun namespace, même pas le namespace global. Sauf que je
viens d'essayer avec mon exemple ci-dessus, en remplaçant C par
std::vector<double>, et ça compile aussi. Alors, pourquoi ça compile
avec mon template dump, et non avec ostream_iterator ?
Une question subsidiaire serait : est-ce que le tout n'est pas un
peu trop compliqué ? Au point, même, que si on se sert des
templates, on ne peut plus savoir si son code est correct ou non.