2012-06-02 1 views
9

Der folgende Code gibt einen Compiler-Fehler (gcc-4.7 laufen mit -std=c++11):Warum kann gcc die Vorlagengröße für Array-Argumente nicht herleiten? (C++ 11)

#include <iostream> 
#include <array> 

template <typename T, int N> 
std::ostream & operator <<(std::ostream & os, const std::array<T, N> & arr) { 
    int i; 
    for (i=0; i<N-1; ++i) 
    os << arr[i] << " "; 
    os << arr[i]; 
    return os; 
} 

int main() { 
    std::array<double, 2> lower{1.0, 1.0}; 
    std::cout << lower << std::endl; 
    return 0; 
} 

Fehlermeldung:

tmp6.cpp: In function ‘int main()’: tmp6.cpp:16:16: error: cannot bind
‘std::ostream {aka std::basic_ostream}’ lvalue to
‘std::basic_ostream&&’ In file included from
/usr/include/c++/4.7/iostream:40:0,
from tmp6.cpp:1: /usr/include/c++/4.7/ostream:600:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT,
_Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits; _Tp = std::array]’

Wenn ich loswerden die Vorlage Funktion Erklärung und ersetzen T mit double und N mit 2, kompiliert es einfach gut (edit:verlassenund ersetzt N mit 2 funktioniert, aber Angabe N=2 als das Standardargument für N funktioniert nicht.).

  1. Weiß jemand, warum gcc das nicht automatisch binden kann?
  2. Wie lautet die Syntax für den Aufruf des Operators << mit explizit angegebenen Vorlagenparametern?

Antwort auf Frage 2:operator<<<double, 2>(std::cout, lower);

Edit: Dies gilt auch für die folgende Funktion, die nur in der Array-Größe Templat ist:

template <int N> 
void print(const std::array<double, N> & arr) { 
    std::cout << "print array here" << std::endl; 
} 

int main() { 
    std::array<double, 2> lower{1.0, 1.0}; 
    print<2>(lower); // this works 
    print(lower); // this does NOT work 
    return 0; 
} 

vielen Dank! viel für Ihre Hilfe.

+1

Beachten Sie, dass Sie 'operator <<' für einen Standardtyp nicht definieren sollten. –

+0

@ K-ballo Irgendeine Idee, wie man eine der beiden nummerierten Fragen in der Post beantworten kann? – user

+0

Wenn ich antworten könnte, hätte ich eine Antwort anstelle eines Kommentars platziert ... Das Problem kommt wahrscheinlich von der falschen Implementierung von Operatoren. –

Antwort

12

Betrachten Sie Ihre Erklärung:

template <typename T, int N> 
std::ostream & operator <<(std::ostream & os, const std::array<T, N> & arr) { 

Die Definition für std::array ist:

template<typename T, std::size_t N> class array {...}; 

Sie verwenden stattdessen int o f std::size_t, und deshalb passt es nicht übereinstimmen.

+0

Riesige +1. Vielen Dank, ich bin mir nicht sicher, ob ich das jemals gefunden hätte. – user

+0

+1 Ich habe gerade gelesen welchen Standard (14.8.2) sagt über Templatabzug und fragte mich, was ich weggelassen habe, denn gegen diese Art von Deduktion gab es nichts. Der falsche Typ in der Template-Definition hat mich auch eingefangen. –

1

Sie können operator<< mit bestimmten Template-Parameter in diesem Aufruf nicht so aestethic, Art und Weise:

operator<< <double,2>(std::cout, lower) << std::endl; 
+0

+1 Ich weiß nicht, warum ich nicht gerade versucht habe-- Ich war so auf dem '<<<', dass ich didn ' Ich denke, der Compiler würde es mögen (ich denke, ich habe projiziert)! – user

Verwandte Themen