2015-11-12 8 views
6

Rozważmy poniższy kod:Domyślna wartość parametru widoczny w szablonie, ale to nie powinno (GCC)

#include <utility> 

void f(int, int); 
void g(int, int); 

struct functor 
{ 
    template<typename... T> 
    void operator()(T&&... params) 
    { 
     return f(std::forward<T>(params)...); 
    } 
}; 

int main() 
{ 
    functor()(1); // can use the default value here, why?! 
    // g(1); // error here as expected, too few arguments 
} 

void f(int a, int b = 42) {} 

void g(int a, int b = 24) {} 

Jest to cienka owijka wokół wywołania funkcji. Jednak wewnątrz functor::operator(), f nie ma domyślnej wartości dla drugiego znanego parametru (jest on widoczny w definicji po main), więc kod nie powinien się kompilować. g ++ 5.2 kompiluje go pomyślnie chociaż, ale dzyń ++ wypluwa oczekiwany komunikat, że oczekuje na kompilatory, które wykonują nazwę dwufazowy odnośnika poprawnie:

error: call to function 'f' that is neither visible in the template definition nor found by argument-dependent lookup return f(std::forward(params)...);

Czy to gcc bug czy ja czegoś brakuje tutaj? Tj., Czy jest punktem tworzenia po definicji f poniżej main()? Ale nawet w tym przypadku nie powinno działać, ponieważ w drugim etapie funkcję można znaleźć tylko poprzez ADL, co nie ma miejsca w tym przypadku.

+2

Koniec jednostki tłumaczeniowej jest również prawidłowym punktem tworzenia instancji. – Jarod42

+0

Tak, ale nadal nie powinno działać, ponieważ w drugiej fazie wykonywane jest tylko ADL. – vsoftco

+0

Jeśli wystąpi na końcu pliku, definicja 'f' z parametrem domyślnym jest widoczna ... Zastanawiam się, czy program nie jest źle sformułowany ... – Jarod42

Odpowiedz

1

[temp.dep.candidate]:

For a function call where the postfix-expression is a dependent name, the candidate functions are found using the usual lookup rules ([basic.lookup.unqual], [basic.lookup.argdep]) except that:

  • For the part of the lookup using unqualified name lookup ([basic.lookup.unqual]), only function declarations from the template definition context are found.

  • For the part of the lookup using associated namespaces ([basic.lookup.argdep]), only function declarations 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.

Zauważ, że ADL nie jest nawet tu pracować, jak zaangażowanych typów mają fundamentalne znaczenie (ich zestaw powiązanych nazw jest pusty).

Powiązane problemy