2016-07-24 7 views
1

Ich möchte einen Vektorraum (dh komponentenweise Addition und Multiplikation mit einem Skalar) über Strukturen mit verschiedenen Komponenten definieren . In diesem kurzen Beispiel überlasten wir operator*= für die spezifische Struktur und verwenden diese dann in Vorlagen für beliebige operator*.Vorlagen zum Überladen von Operatoren: error: overloaded 'operator *' muss mindestens einen Parameter der Klasse oder des Enumerationstyps haben

Der folgende Code kompiliert und ausgeführt:

#include <assert.h> 


struct myfloat3 { float x, y, z; }; 


myfloat3 operator*=(myfloat3& a, const float b) { 
    a.x *= b; a.y *= b; a.z *= b; 
    return a; 
} 

template<typename Pt> 
Pt operator*(const Pt& a, const float b) { 
    auto prod = a; 
    prod *= b; 
    return prod; 
} 

// template<typename Pt> 
// Pt operator*(const float b, const Pt& a) { 
//  auto prod = a; 
//  prod *= b; 
//  return prod; 
// } 


int main(int argc, char const *argv[]) { 
    myfloat3 x {1, 2, 3}; 

    assert((x*3.0f).x == 3); 

    return 0; 
} 

Aber wenn ich die zweite Überlast für die andere Ordnung Kommentar-, float * myfloat3, ich

$ g++ -std=c++11 sandbox/overload.cpp 
sandbox/overload.cpp:20:4: error: overloaded 'operator*' must have at least one 
     parameter of class or enumeration type 
Pt operator*(const float b, const Pt& a) { 
^
sandbox/overload.cpp:30:14: note: in instantiation of function template 
     specialization 'operator*<float>' requested here 
    assert((x*3.0f).x == 3); 
      ^
/usr/include/assert.h:93:25: note: expanded from macro 'assert' 
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE... 
         ^
1 error generated. 

$ g++ --version 
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) 
Target: x86_64-apple-darwin13.4.0 
Thread model: posix 

jedoch einen anderen Compiler funktioniert es:

$ g++ --version 
g++ (Ubuntu 4.9.2-10ubuntu13) 4.9.2 
$ g++ -std=c++11 sandbox/soverload.cpp 

Irgendwelche Ideen?

+1

https://Stackoverflow.com/q/18596412/4326278 ist relevant, aber beachten Sie die Kommentare zur angenommenen Antwort. – bogdan

+0

Danke, ich werde diese SFINA-Magie versuchen, wenn ich wieder mit dem beschwerenden Compiler auf meinem Laptop bin. – qiv

Antwort

0

ein Merkmal Klasse mit enable_if verwenden zu steuern, wenn die Vorlage aktiviert ist:

template<typename Pt> struct Is_vector: public std::false_type {}; 
template<> struct Is_vector<float3>: public std::true_type {}; 

template<typename Pt> 
typename std::enable_if<Is_vector<Pt>::value, Pt>::type 
operator*(const Pt& a, const float b) { 
    auto prod = a; 
    prod *= b; 
    return prod; 
} 

template<typename Pt> 
typename std::enable_if<Is_vector<Pt>::value, Pt>::type 
operator*(const float b, const Pt& a) { 
    auto prod = a; 
    prod *= b; 
    return prod; 
} 

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/enable-if und Thrust reduction and overloaded operator-(const float3&, const float3&) won't compile Erläuterungen siehe.