【发布时间】:2016-11-21 16:27:23
【问题描述】:
我有以下示例代码,简化为基本代码,可以使用 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;
}
clang 告诉我: prog.cc:12:34:错误:'_p' 是 'outer::foo' 的私有成员 返回 std::make_tuple(c._p...);
我不明白为什么 clang 不识别朋友声明。这是clang的错误还是所有其他编译器的问题?
当我将 foo 设为非模板类时,clang 不会抱怨。 任何解决方法的想法?
在此先感谢
【问题讨论】:
-
this 不回答你的问题吗?
-
作为一种解决方法,您可以使用
friend auto test::bar_(A&&, B&&, C&&... c) -> decltype(std::make_tuple(c._p...));作为朋友(以及bar_)函数签名。 live demo -
我搜索了variadic和friend的组合。但我没有意识到汽车是问题所在。是的,是问题所在,明确指定返回类型解决了问题。由于实际的返回类型要复杂得多,所以我没有尝试过。非常感谢!
-
所以也许将函数包装到一个友好的虚拟结构中会更适合你:example
-
@W.F.我进一步工作,即使使用明确的返回类型,仍然存在问题。使用 Clang 的编译现在在开始时通过,但是当它稍后进行实例化时,它再次失败。您的带有包装器的解决方案现在可以解决这个问题。如果您会“回答”,我会将其投票为我的问题的解决方案。非常感谢!
标签: c++ templates c++14 variadic-templates clang++