2017-08-14 4 views
2

Ich beobachte ein seltsames Verhalten, das ich nicht ganz erklären kann. Der Code sieht wie folgt aus:GCC 7 Kompilierung Fehler bei der Verwendung von Std :: Addressof

#include <memory> 
#include <vector> 
#include <algorithm> 

int main(){ 
    std::vector<double> t1(10, 5.0); 
    std::vector<double*> t2(10); 
    std::transform(t1.begin(), t1.end(), t2.begin(), std::addressof<double>); 
    //std::transform(t1.begin(), t1.end(), t2.begin(), [](double& a){return &a;}); 
} 

Und hier ist eine Version mit https://godbolt.org/g/YcNdbf Das Problem herum zu spielen ist, dass dieser Code kompiliert fein gcc4.9-6.3 verwenden, aber nicht unter gcc 7.1. Clang mag es auch nicht.

(edit) Fehlermeldungen von gcc 7.1:

<source>: In function 'int main()': 
8 : <source>:8:76: error: no matching function for call to 'transform(std::vector<double>::iterator, std::vector<double>::iterator, std::vector<double*>::iterator, <unresolved overloaded function type>)' 
    std::transform(t1.begin(), t1.end(), t2.begin(), std::addressof<double>); 
                      ^
In file included from /opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/algorithm:62:0, 
       from <source>:3: 
/opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/bits/stl_algo.h:4281:5: note: candidate: template<class _IIter, class _OIter, class _UnaryOperation> _OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) 
    transform(_InputIterator __first, _InputIterator __last, 
    ^~~~~~~~~ 
/opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/bits/stl_algo.h:4281:5: note: template argument deduction/substitution failed: 
8 : <source>:8:76: note: could not resolve address from overloaded function 'addressof<double>' 
    std::transform(t1.begin(), t1.end(), t2.begin(), std::addressof<double>); 
                      ^
In file included from /opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/algorithm:62:0, 
       from <source>:3: 
/opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/bits/stl_algo.h:4318:5: note: candidate: template<class _IIter1, class _IIter2, class _OIter, class _BinaryOperation> _OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation) 
    transform(_InputIterator1 __first1, _InputIterator1 __last1, 
    ^~~~~~~~~ 
/opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/bits/stl_algo.h:4318:5: note: template argument deduction/substitution failed: 
8 : <source>:8:76: note: could not resolve address from overloaded function 'addressof<double>' 
    std::transform(t1.begin(), t1.end(), t2.begin(), std::addressof<double>); 
                      ^
Compiler exited with result code 1 

Allerdings kann ich nicht ganz verstehen, warum es nicht funktioniert.

Vielen Dank im Voraus für jeden Versuch, die Adresse von Provisorien Einnahme versehentlich zu vermeiden :)

+1

Bitte mo Re spezifisch als "fehlschlägt" und "mag es nicht". Fügen Sie wörtliche Fehlermeldungen ein. – molbdnilo

+1

'addressof' nimmt einen Variablennamen anstelle eines Typennamens – meowgoesthedog

+0

Entschuldigung, ich dachte, es ist einfacher, es in godbolt zu betrachten, aber ich denke, du hast recht, dass es Sinn macht, sie auch hier zu haben, also fügte ich sie hinzu;) | Und @meowgoesthedog nicht sicher, was Sie meinen, wird die Variable an die Funktion über die Transformation übergeben und man muss nur die Vorlage Parameter richtig angeben? – Christoph

Antwort

5

Um zu helfen, hat die Bibliothek eine zweite bekommen (gestrichen) Signatur für addressof:

template <class T> constexpr T* addressof(T& r) noexcept; 
template <class T> const T* addressof(const T&& elem) = delete; 

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2598 Siehe

Nun weiß der Compiler nicht, ob der Code mit der gelöschten Funktion übereinstimmen soll oder nicht ...

+0

Oh wow, ich habe irgendwie angenommen, dass diese gelöschten Überladungen nicht an der Überladungsauflösung teilnehmen werden ... Vielen Dank für die Antwort! Das bedeutet, dass ich keine andere Möglichkeit habe, als diesen Call in ein Lambda zu verpacken, oder? – Christoph

+1

@Christoph gelöscht Überladungen existieren speziell zur Teilnahme an Überladung Auflösung und geben eine Kompilierungszeit Fehler für jeden Funktionsaufruf, die zu ihnen gelöst werden würde. Sonst wären sie völlig nutzlos. –

+0

@Revolver_Ocelot danke für die Erklärung :) Das macht für mich völlig Sinn, ich denke, ich habe nie bewusst diese Verbindung gemacht: P – Christoph

Verwandte Themen