function template overload resolution und dependant names

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

function template overload resolution und dependant names

Beitrag von kaiserludi »

Moin.

In folgendem Code wird von VC++ wie gewünscht das Template ausgewählt:

Code: Alles auswählen

struct FooBar
{
};

class Foo
{
public:
	template<typename T> static void bar(T t){}
	static void bar(FooBar b){}
};

int main(void)
{
	Foo foo;
	foo.bar(1);
}
Hier hingegen wird von VC++ plötzlich der Overload für FooBar gewählt, obwohl er gar nicht passt:

Code: Alles auswählen

struct FooBar
{
};

class Foo
{
public:
	template<typename T> static void bar(typename std::enable_if<!std::is_pointer<T>::value,T>::type t){}
	static void bar(FooBar b){}
};

int main(void)
{
	foo::bar(1);
}
Entsprechend gibts eine Fehlermeldung
error C2664: 'void Foo::bar(FooBar)' : cannot convert parameter 1 from 'int' to 'FooBar'
Jemand eine Idee, wieso das so ist und wie man den Compiler dazu bekommt, trotzt dependant name lookup das Template zu wählen?

Edit:
Code simplifiziert und vereinheitlicht.

Edit2: überflüssige Semikola entfernt.
Zuletzt geändert von kaiserludi am 04.07.2013, 18:50, insgesamt 1-mal geändert.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: function template overload resolution und dependant name

Beitrag von CodingCat »

Morgen
Deduktion von Template-Argumenten geht NUR in reiner Typkonstruktornotation. Sobald du abhängige Namen nutzt, schaltest du für den entsprechenden Parameter automatisch Deduktion ab (Deduktion wäre hier von Seiten des Compilers auch kaum sinnvoll umzusetzen). In C++11 tust du folgendes:

Code: Alles auswählen

template <
   typename T,
   typename = typename std::enable_if<!std::is_pointer<T>::value>::type
> static void bar(T t) { }
Heute
Da dein VC mit großer Wahrscheinlichkeit noch nicht auf dem notwendigen Stand ist, musst du dich mit folgendem begnügen:

Code: Alles auswählen

template <
   typename T
> static typename std::enable_if<!std::is_pointer<T>::value, void>::type bar(T t) { }
Übermorgen
Mit C++14 ginge mit Template-Variablen und constexpr eventuell folgendes:

Code: Alles auswählen

template <
   typename T,
   typename = typename imaginary_std::enable_if<!imaginary_std::is_pointer<T>>::type
> static void bar(T t) { }
Ich befürchte aber, eine solche verbesserte imaginary_std wird nicht so bald mitgeliefert.

Weiterhin wird momentan an Concepts Lite gewerkelt, die es ebenfalls noch in C++14 schaffen könnten(?):

Code: Alles auswählen

template <imaginary_std::NoPointer T>
static void bar(T t) { }
oder

Code: Alles auswählen

template <typename T> requires !imaginary_std::IsPointer<T>()
static void bar(T t) { }
oder

Code: Alles auswählen

template <typename T> requires !std::is_pointer<T>::value
static void bar(T t) { }
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: function template overload resolution und dependant name

Beitrag von kaiserludi »

"Morgen" erzeugt mir:
error C4519: default template arguments are only allowed on a class template
"Heute" funzt. Mag zwar nicht super schick sein, die Validierung des Parameters beim Returntype zu machen (und ich wäre von alleine wohl auch nicht so schnell auf die Idee gekommen), aber es funktionert und ist verständlich und das reicht mir in diesem Fall mehr als aus.

"Übermorgen" Nummer 2 wäre natürlich ideal, aber das ist dann wohl noch Zukunftsmusik.

Ich schulde dir ein weiteres Bier :mrgreen:
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Antworten