Tôi có mã mẫu sau đây, được giảm xuống mức cần thiết, biên dịch với gcc 6.1, gcc 7.0 head và Visual Studio 2015/2017RC, nhưng không có bất kỳ phiên bản nào.Tại sao clang từ chối chức năng của bạn bè mẫu variadic
#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;
}
kêu vang nói với tôi: prog.cc:12:34: lỗi: '_P' là một thành viên tư nhân 'ngoài :: foo' trở std :: make_tuple (c._p ...) ;
Tôi không hiểu tại sao clang không nhận ra tuyên bố kết bạn. Đây có phải là một lỗi của clang hay nó là một vấn đề của tất cả các trình biên dịch khác?
Khi tôi tạo foo một lớp không phải mẫu, tiếng kêu không kêu la. Bất kỳ ý tưởng nào cho giải pháp thay thế?
Nhiều cảm ơn trước
Liệu không [này] (http://stackoverflow.com/questions/32889492/friend-function-template-with-automatic-return- type-deduction-cannot-access-a-pr) trả lời câu hỏi của bạn? –
Để giải quyết sự cố, bạn có thể sử dụng 'kiểm tra tự động của người bạn :: bar_ (A &&, B &&, C && ... c) -> decltype (std :: make_tuple (c._p ...)); 'làm bạn (cũng như dưới dạng chữ ký 'bar_'). [live demo] (http://melpon.org/wandbox/permlink/CEBDjgZGGLbAtWY1) –
Tôi đã tìm kiếm sự kết hợp của variadic và bạn bè. Nhưng tôi đã không nhận ra sự tự động là vấn đề. Có, là vấn đề và rõ ràng xác định kiểu trả về đã giải quyết được vấn đề. Vì kiểu trả về thực tế phức tạp hơn nhiều nên tôi không thử nó. Cảm ơn nhiều! –