Ich habe den folgenden Beispielcode, reduziert auf das Wesentliche, das kompiliert mit Gcc 6.1, GCC 7.0 Kopf und Visual Studio 2015/2017RC, aber nicht mit irgendeiner Clang-Version.Warum Clang Variadic Vorlage Freund Funktion
#include <iostream>
#include <tuple>
using namespace std;
namespace outer {
namespace test {
template <typename A, typename B, typename...C>
auto bar_(A&&, B&&, C&&... c) {
return std::make_tuple(c._p...);
}
}
template <typename A, typename B, typename...C>
auto bar(A a, B b, C&&... c) {
return test::bar_(std::move(a), std::move(b), std::forward<C>(c)...);
}
template<typename T>
class foo
{
template <typename A, typename B, typename...C>
friend auto test::bar_(A&&, B&&, C&&... c);
int _p;
public:
foo(int f) : _p(f) {}
};
}
int main() {
outer::foo<int> a1(1);
outer::foo<int> a2(2);
auto result = outer::bar(2.3, 4.5, a1, a2);
cout << get<0>(result) << " " << get<1>(result) << '\n';
return 0;
}
Klirren sagt mir: prog.cc:12:34: Fehler: '_p' ist ein privates Mitglied von 'Außen :: foo' return std :: make_tuple (c._p ...) ;
Ich verstehe nicht, warum Clang die Freundschaftsdeklaration nicht erkennt. Ist das ein Bug des Klangs oder ist es ein Problem aller anderen Compiler?
Wenn ich foo eine Nicht-Vorlage-Klasse mache, klagt clang nicht. Irgendwelche Ideen für eine Problemumgehung?
Vielen Dank im Voraus
Does not [diese] (http://stackoverflow.com/questions/32889492/friend-function-template-with-automatic-return- type-deduction-can not-access-a-pr) Beantworten Sie Ihre Frage? –
Als Workaround könntest du 'friendautotest :: bar_ (A &&, B &&, C && ... c) -> decltype (std :: make_tuple (c._p ...));' als Freund benutzen als 'bar_') Funktionssignatur. [Live-Demo] (http://melpon.org/wandbox/permlink/CEBDjgZGGLbAtWY1) –
Ich suchte nach der Kombination von variadic und Freund. Aber ich wusste nicht, dass das Auto das Problem war. Ja, ist das Problem und explizite Angabe des Rückgabetyps löste das Problem. Da der tatsächliche Rückgabetyp viel komplizierter ist, habe ich es nicht versucht. Danke vielmals! –