Fel*_*oni 12 c++ templates variadic-templates clang++ c++14
我有以下示例代码,简化为必需的,编译与gcc 6.1,gcc 7.0 head和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;
}
Run Code Online (Sandbox Code Playgroud)
clang告诉我:prog.cc:12:34:错误:'_ p'是'outer :: foo'的私有成员return std :: make_tuple(c._p ...);
我不明白为什么clang不承认朋友的声明.这是一个铿锵的错误还是所有其他编译器的问题?
当我使foo成为非模板类时,clang不会抱怨.任何解决方法的想法?
提前谢谢了
作为“为什么?” 这个问题在这个线程中进行了深入讨论,我将只关注可能的解决方法。您可以尝试将您的函数包装到一个虚拟结构中,以确保它的所有可能的重载也包含在您的foo. 解决方法建议如下:
#include <iostream>
#include <tuple>
using namespace std;
namespace outer {
namespace test {
struct wrapper{
template <typename A, typename B, typename...C>
static 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::wrapper::bar_(std::move(a), std::move(b), std::forward<C>(c)...);
}
template<typename T>
class foo
{
friend struct test::wrapper;
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
301 次 |
| 最近记录: |