2010-12-31 2 views
11

ich einen solchen Code haben, die gut funktioniert:Warum Code mit lokalen Struktur als Parameter für die STL-Funktion nicht in g ++ kompilieren?

#include <algorithm> 
#include <iostream> 

char x[11]= "ABCDEFGHIJ"; 
char y[11]; 

struct F { 
    char operator() (char c) const 
    { return c+1; } 
}; 

int main() 
{ 
    std::transform(x, x+10, y, F()); 
    y[10] = 0; std::cout <<y <<std::endl; 
} 

Aber wenn ich es auf diese Art zu ändern:

#include <algorithm> 
#include <iostream> 

char x[11]= "ABCDEFGHIJ"; 
char y[11]; 

int main() 
{ 
    struct F { 
     char operator() (char c) const 
     { return c+1; } 
    }; 
    std::transform(x, x+10, y, F()); 
    y[10] = 0; std::cout <<y <<std::endl; 
} 

Es wird nicht kompilieren, sagen:

error: no matching function for call to ‘transform(char [11], char*, char [11], main()::F)’

Was ist los?

GCC-Version ist 4.4, die Lambda-Ausdrücke nicht erkennt.

+0

kompilieren Sie wie C++ 03 oder C++ 0x? –

Antwort

10

In C++ - 98/03 ist der zweite Code nicht gültig, da F ein lokaler Typ ist; in Fakten, bei §14.3.1.2 ist es, dass

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

[Example:

template <class T> class X { /* ... */ }; 
void f() 
{ 
    struct S { /* ... */ }; 
    X<S> x3;   // error: local type used as template-argument 
    X<S*> x4;  // error: pointer to local type used as template-argument 
} 

—end example] [Note: a template type argument may be an incomplete type (3.9). ]

In C++ - 0x diese Einschränkung entfernt wird; im selben Abschnitt, der neue Standard Entwurf (N3126) zeigt dies ausdrücklich im Beispiel:

[ Example:

template <class T> class X { }; 
template <class T> void f(T t) { } 
struct { } unnamed_obj; 

void f() { 
    struct A { }; 
    enum { e1 }; 
    typedef struct { } B; 
    B b; 
    X<A> x1;    // OK 
    X<A*> x2;   // OK 
    X<B> x3;    // OK 
    f(e1);    // OK 
    f(unnamed_obj);  // OK 
    f(b);    // OK 
} 

— end example ] [ Note: a template type argument may be an incomplete type (3.9). — end note ]

+1

Wir sind in C++ 03 oder C++ 0x, nicht C++ 98 mehr. Natürlich ist der Punkt immer noch gültig, aber das Zitat aus einem veralteten Standard ist bedeutungslos. – Puppy

+0

@DeadMG: Leider konnte ich keinen freien Entwurf von C++ 03 finden, daher muss ich bei C++ 98 für Zitate bleiben: ('; trotzdem habe ich die inoffizielle Liste der Änderungen überprüft und §14.3 nicht in den Änderungen enthalten, so sollte das Zitat noch gültig sein für C++ 03. –

+0

Ich sehe ... wissen Sie, warum solche Beschränkung kam? – RnMss

4

g ++ 4.5.1 compiles your code (mit -std=c++0x option).

Ihr zweites Codebeispiel ist schlecht ausgebildet in C++ 03 aber gültig in C++ 0x

std::transform ist

template < class InputIterator, class OutputIterator, class UnaryOperator > 
    OutputIterator transform (InputIterator first1, InputIterator last1, 
          OutputIterator result, UnaryOperator op); 

jedoch g ++ 4.4 doesn't support local types as template arguments (auch mit - std=c++0x Option ]

1: Ein lokaler Typ, ein Typ ohne Verknüpfung, ein unbenannter Typ oder ein Typ, der aus einem dieser Typen zusammengesetzt ist, dürfen nicht als Template-Argument für einen Template-Type-Parameter verwendet werden. (ISO C++ 03 §14.3.1.2)

+0

Ich kannte den Parameter "-std = C++ 0x" nicht, danke. – RnMss

Verwandte Themen