Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

std::tuple C++11 Frage

8 views
Skip to first unread message

Markus Donath

unread,
Aug 30, 2018, 4:40:04 PM8/30/18
to
Ich benutze 2 Compiler (RAD Studio 10.2 mit clang 3.3 und MSVC 15.8.2).
Mit beiden geht:

std::list<std::pair<int, int>> prl {
{ 1, 1 },
{ 1, 2 },
{ 2, 1}
};

aber:

std::list<std::tuple<int, int, int>> tpl {
{ 1, 1, 1 },
{ 1, 1, 2 },
{ 1, 2, 1 }
};

geht nur mit dem MSVC.

Warum kann das der clang 3.3 nicht? Wird irgendein Feature verwendet,
was noch nicht durch den C++ 11 Standard abgedeckt ist sonder erst durch
C++ 14 oder C++ 17?

Markus

Stefan Ram

unread,
Aug 31, 2018, 2:20:03 AM8/31/18
to
Markus Donath <nn...@online.de> writes:
>std::list<std::tuple<int, int, int>> tpl {
> { 1, 1, 1 },

In n4296 (2014-11-19) war der Paar-Konstruktor nicht-explizit
(n4296, 20.3.2, »constexpr pair(const T1& x, const T2& y);«),
während der Tupel-Konstruktor explizit war
(n4296, 20.4.2.1, »constexpr explicit tuple(const Types&...);«),
und zur Umwandlung der Einträge einer Initialisierungsliste
wird ein nicht-expliziter Konstruktor benötigt
(nur mit gcc ausprobiert, keine Quelle dafür gefunden).

In n4762 (2018-07-07) ist der Tupel-Konstruktor (n4762, 19.5.3.1p6
»explicit(see below) constexpr tuple(const Types&...);«) nur noch
explizit wenn
»!conjunction_v<is_convertible<const Types&, Types>...>« (p8),
was für »int«s wohl »false« ist.

Alternative:

|::std::list< ::std::tuple< int, int, int >>tlist
|{ ::std::make_tuple( 1, 1, 1 )};

.

Stefan Ram

unread,
Aug 31, 2018, 7:00:04 PM8/31/18
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:
>(n4296, 20.4.2.1, »constexpr explicit tuple(const Types&...);«),
>und zur Umwandlung der Einträge einer Initialisierungsliste
>wird ein nicht-expliziter Konstruktor benötigt
>(nur mit gcc ausprobiert, keine Quelle dafür gefunden).

Keine Quelle gefunden, weil es vielleicht nicht stimmt!

Das folgende Programm wird von einer neueren Version von gcc
akzeptiert, aber von einer etwas älteren Version von clang
zurückgewiesen (»no matching constructor for initialization
of '::std::tuple<ex>'«).

main.cpp

#include <iostream>
#include <ostream>
#include <string>
#include <tuple>

using namespace ::std::literals;

struct im { im( int ){} };
struct ex { explicit ex( int ){} };

int main()
{ ::std::tuple< im >im{ 1 };
::std::tuple< ex >ex{ 1 };
::std::cout << "done.\n"s; }

In n4762 fand ich nach erneuter Suche immer noch keine
Stelle, die besagt, daß eine initializer-clause einen
nicht-expliziten Konstruktor verlangt.

Die Antwort auf Markus' Frage ist also noch nicht gefunden!

Markus Donath

unread,
Sep 13, 2018, 8:40:04 AM9/13/18
to
Ich glaube, mein clang ist einfach zu alt. Schon wieder etwas gefunden,
was er nicht kann, womit aber der MSVC keine Probleme hat:

void foo(function<void(int)> f) {
int x{ 12345 };
f(x);
}

void foo(function<void(double*)> f) {
double x{ 5432.1 };
f(&x);
}

void bar() {
foo([](int x) {
cout << x << endl;
});
foo([](double* x) {
cout << *x << endl;
});
}

[bcc64 Error] test.cpp(11): call to 'foo' is ambiguous

sagt der Kompiler. Wieso kann er die Typen des Parameters von foo nicht
auseinanderhalten?

Markus
0 new messages