Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.iso-c++ > #2063

Re: Overloading-Problem

From SG <s.gesemann@gmail.com>
Newsgroups de.comp.lang.iso-c++
Subject Re: Overloading-Problem
Date 2017-08-13 03:12 -0700
Organization A noiseless patient Spider
Message-ID <e2a1d1b0-b207-4bbc-8456-06b2b5d5126c@googlegroups.com> (permalink)
References <oko9n8.3qc.1@stefan.msgid.phost.de>

Show all headers | View raw


Am Mittwoch, 19. Juli 2017 19:00:05 UTC+2 schrieb Stefan Reuther:
> 
> template<typename T>
> class foo {
>  public:
> 
>    foo(const foo& f)   //1
> 
>    template<typename U>
>    foo(U&& u)          //2
> 
> };
> 
> void bar() {
>    foo<std::string> a;
>    foo<std::string> b(a); //3
> }
> ----8<--------8<--------8<--------8<--------8<----
> 
> In Zeile //3 wählt der Compiler (z.B. g++-5.4.0 -std=c++11) den Overload
> //2 und beschwert sich dann, dass er das keinen passenden
> Zuweisungsoperator für 'm = u' findet.
> 
> Erwartet hätte ich, dass Overload //1 gewählt wird. Wenn ich //2
> auskommentiere, ist das auch der Fall.
> 
> Gewohnt bin ich aus C++98, dass der Compiler gerade fürs Kopieren eines
> Objektes einen Template-Konstruktor nicht einmal zur Kenntnis nimmt.

Das war aber noch nie so.

> Wie bekomme ich das aufgelöst?

Wegen //3 wird bei //2 der Parameter U mit foo<string>& deduziert und
ist ein besserer Match als //1, weil da bei //1 noch ein const dazu
kommen würde.

Eine Möglichkeit wäre, dem zweiten Konstruktor quasi einen Namen
geben. Das findest Du so so ähnlich auch bei std::pair. Das Ding hat
nämlich folgenden Konstruktor ab C++11:

   template< class... Args1, class... Args2 >
   pair( std::piecewise_construct_t,
         std::tuple<Args1...> first_args,
         std::tuple<Args2...> second_args );

Aufrufen tut man den dann so:

   pair<T,U> x (std::piecewise_construct,
      std::forward_as_tuple(...),
      std::forward_as_tuple(...) );

Der erste "dummy" Parameter ist quasi der Name des Konstruktors.

Du kannst aber auch sowas schreiben, wenn Du magst:

    template<typename U
       ,class = typename std::enable_if<
          std::is_constructible<T,U&&>::value
       >::type
    >
    foo(U&& u)
    : m(std::forward<U>(u))
    {}

(Bei dem type-trait bin ich mir gerade nicht sicher. Habe ich
jetzt nicht extra nachgeguckt)

Back to de.comp.lang.iso-c++ | Previous | NextPrevious in thread | Find similar | Unroll thread


Thread

Overloading-Problem Stefan Reuther <stefan.news@arcor.de> - 2017-07-19 18:51 +0200
  Re: Overloading-Problem Florian Weimer <fw@deneb.enyo.de> - 2017-07-19 21:37 +0200
    Re: Overloading-Problem Stefan Reuther <stefan.news@arcor.de> - 2017-07-21 20:09 +0200
      Re: Overloading-Problem SG <s.gesemann@gmail.com> - 2017-08-13 05:40 -0700
  Re: Overloading-Problem SG <s.gesemann@gmail.com> - 2017-08-13 03:12 -0700

csiph-web