2009-12-17 6 views
14

Warum ist dieser automatische Typabzug nur für Funktionen und nicht für Klassen möglich?Vorlage Typ Abzug in C++ für Klasse vs Funktion?

+0

Haben Sie 'std :: vector a sprechen (1, wahr); 'oder über' std :: vector v = std :: vector (1, wahr); '? Die erste wird "wahre" Deduktion sein, während die zweite ein bereits bekanntes Argument erfordert. Beachten Sie die Komplikation der expliziten Spezialisierung bool-vector. –

+0

Der erste, wahre Abzug, ist das nicht möglich? – yesraaj

+0

Ich habe gerade Bjarne Stroustrups Argument dafür gefunden, dies in der Sprache nicht zu berücksichtigen. –

Antwort

17

In bestimmten Fällen können Sie immer wie std::make_pair tun:

template<class T> 
make_foo(T val) { 
    return foo<T>(val); 
} 

EDIT: Ich habe gerade folgend in "The C++ Programming Language, Third Edition", Seite 335. Bjarne sagen:

Beachten Sie, dass Klassenschablonenargumente nie abgeleitet werden. Der Grund ist, dass die Flexibilität von mehreren Konstruktoren für eine Klasse solche Abzug unmöglich in vielen Fällen und obskuren in vielen mehr.

Dies ist natürlich sehr subjektiv. Es gibt einige Diskussionen darüber in comp.std.c++ und der Konsens scheint zu sein, dass es keinen Grund gibt, warum es konnte nicht unterstützt werden. Ob es eine gute Idee wäre oder nicht, ist eine andere Frage ...

+0

Das ist, was ich fragen, warum müssten Sie eine Klasse innerhalb einer Funktion, wie sie es in boost :: bind bought: – yesraaj

+1

Die Flexibilität von mehreren Konstruktoren bietet nicht weniger oder mehr als die Flexibilität durch mehrere Überladungen zur Verfügung gestellt. – Puppy

1

Ich denke, dass implizite Typumwandlung nur auf Funktionsargumente nur anwendbar ist, damit der Compiler es ableiten kann, um den Funktionsaufruf erfolgreich zu machen.

Aber wie kann es ableiten, welchen Typ Sie es Klasse haben möchten.

Wir müssen 4 so einen Tag warten, wenn wir AI basierten Compiler haben, um unsere Gedanken zu lesen.

+9

-1 Soweit ich weiß, sind psychische Kräfte nicht Teil eines AI-Forschungsprogramms. Während ich erkenne, dass Englisch nicht jedermanns Muttersprache ist, ist der Missbrauch von "4" unverzeihlich. –

+0

+1 sagte warten bis zu den Tagen, wenn Compiler "wissen können, was Sie versuchen zu tun" und sehr zuverlässig sein ... es ist eine Möglichkeit. Fügen Sie dem Makefile einfach eine Markierung hinzu. –

+0

Keine KI erforderlich - GCC7 beansprucht Unterstützung für den Templatargumentabzug für Klassenvorlagen: https://gcc.gnu.org/projects/cxx-status.html http://www.open-std.org/jtc1/sc22/wg21 /docs/papers/2016/p0091r3.html Also halt einfach ein bisschen länger. ;) – Xupicor

4

Im Falle eines Funktionsaufrufs leitet der Compiler den Vorlagentyp vom Argumenttyp ab. Zum Beispiel die std::max-Funktion. Der Compiler verwendet den Typ der Argumente, um den Vorlagenparameter abzuleiten. Dies funktioniert nicht immer, da nicht alle Anrufe eindeutig sind.

int a = 5; 
float b = 10; 

double result1 = std::min(a, b); // error: template parameter ambigous 
double result2 = std::min<double>(a, b); // explicit parameter enforces use of conversion 

Bei einer Vorlagenklasse ist das nicht immer möglich. Nehmen wir zum Beispiel diese Klasse:

template< class T> 
class Foo { 
public: 
    Foo(); 
    void Bar(int a); 
private: 
    T m_Member; 
}; 

Der Typ T nie in einem Funktionsaufruf angezeigt wird, so dass der Compiler überhaupt keinen Hinweis hat, welche Art verwendet werden soll.

+0

So ist es nicht immer möglich, aber, wie Sie betonen, auch nicht für Funktionen. Das erklärt nicht wirklich warum es nicht unterstützt wird. –

+0

Ich weiß nicht, warum es nicht unterstützt wird (eine Best-Effort-Lösung wäre denkbar), aber die Frage war, ob es möglich ist. Ich denke, ich habe das beantwortet, deshalb verstehe ich den Downvote nicht. –

+0

Ich denke, er fragte * warum * es ist nicht möglich, nicht * ob * es möglich ist. –

9

Bei Kona meeting Template-Parameter Abzug für Konstrukteure (P0091R0) genehmigt wurde, was bedeutet, dass in C++ 17 wir in der Lage sein zu schreiben:

pair p1{"foo"s, 12}; 
auto p2 = pair{"foo"s, 12}; 
f(pair{"foo"s, 12});