以下のサンプルコードをgcc 6.1、gcc 7.0ヘッド、Visual Studio 2015/2017RCでコンパイルする必要があります。なぜclangは可変のテンプレートフレンド機能を拒否するのですか
#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;
}
打ち鳴らすには、私に語った: prog.cc:12:34:エラー: '_p' 'は、外側:: foo' で リターンのstd :: make_tuple(c._p ...)の民間メンバーであります;
なぜclangが友人宣言を認識しないのかわかりません。これはclangのバグですか、それとも他のすべてのコンパイラの問題ですか?
fooをテンプレート以外のクラスにすると、clangは文句を言わない。 回避策の候補はありますか?事前
ていません[この](http://stackoverflow.com/questions/32889492/friend-function-template-with-automatic-return-タイプ控除 - あなたの質問に答えてもらえませんか? –
回避策として、 'friend auto test :: bar_(A &&、B &&、C && ... c) - > decltype(std :: make_tuple(c._p ...));'を友人として使うこともできます'bar_'として)関数シグネチャを返します。 [ライブデモ](http://melpon.org/wandbox/permlink/CEBDjgZGGLbAtWY1) –
私はvariadicとfriendの組み合わせを探しました。しかし、私は自動車が問題であることを認識していませんでした。はい、問題はありますか、戻り値の型を明示的に指定すると問題が解決しました。実際の戻り値の型ははるかに複雑なので、試していませんでした。どうもありがとう! –