Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ a<;T>;也是a的朋友<;A<;T>>;?_C++_C++14_Friend_Friend Function - Fatal编程技术网

C++ a<;T>;也是a的朋友<;A<;T>>;?

C++ a<;T>;也是a的朋友<;A<;T>>;?,c++,c++14,friend,friend-function,C++,C++14,Friend,Friend Function,考虑以下代码: #include <vector> template<typename T> class Container; template<typename T> Container<Container<T>> make_double_container(const std::vector<std::vector<T>>&); template<typename T> class C

考虑以下代码:

#include <vector>

template<typename T> class Container;
template<typename T> Container<Container<T>> make_double_container(const std::vector<std::vector<T>>&);

template<typename T>
class Container {
    std::vector<T> v;
    friend Container<Container<T>> make_double_container<T>(const std::vector<std::vector<T>>&);

public:
    Container() {}
    explicit Container(std::vector<T> v) : v(v) {}
};

template<typename T>
Container<Container<T>> make_double_container(const std::vector<std::vector<T>>& v) {
    Container<Container<T>> c;
    for(const auto& x : v) {
        c.v.push_back(Container<T>(x));
    }
    return c;
}

int main() {
    std::vector<std::vector<int>> v{{1,2,3},{4,5,6}};
    auto c = make_double_container(v);
    return 0;
}
#包括
模板类容器;
模板容器生成双容器(const std::vector&);
模板
类容器{
std::向量v;
朋友容器make_double_容器(const std::vector&);
公众:
容器(){}
显式容器(std::vector v):v(v){}
};
模板
容器制造双容器(const std::vector&v){
容器c;
用于(常数自动和x:v){
c、 v.向后推(容器(x));
}
返回c;
}
int main(){
std::向量v{{1,2,3},{4,5,6};
自动c=制造双容器(v);
返回0;
}
编译器告诉我:

main.cpp: In instantiation of 'Container<Container<T> > make_double_container(const std::vector<std::vector<T> >&) [with T = int]':
main.cpp:27:37:   required from here
main.cpp:8:20: error: 'std::vector<Container<int>, std::allocator<Container<int> > > Container<Container<int> >::v' is private
     std::vector<T> v;
                    ^
main.cpp:20:9: error: within this context
         c.v.push_back(Container<T>(x));
main.cpp:Container make_double_Container(const std::vector&)[with T=int]的实例化中:
main.cpp:27:37:此处需要
main.cpp:8:20:错误:“std::vector Container::v”是私有的
std::向量v;
^
main.cpp:20:9:错误:在此上下文中
c、 v.向后推(容器(x));

我认为这是正确的,因为
make_double\u container
container
的朋友,而不是
container
的朋友。在这种情况下,如何使
make\u double\u container
工作?

make\u double\u container
定义为
S
的模板函数似乎可以使其编译并工作

template<typename T>
class Container {
    std::vector<T> v;

    template<class S>
    friend Container<Container<S>> make_double_container(const std::vector<std::vector<S>>&);

public:
    Container() {}
    explicit Container(std::vector<T> v) : v(v) {}
};
T
实际上是
Container
,而
make\u double\u Container
变成了

Container<Container<Container<T>>> make_double_container(const std::vector<std::vector<Container<T>>>&); 
容器制造双容器(const std::vector&); 然后(在主管道内)进入

容器制造双容器(const std::vector&); 将友谊变成:

 template<class S>
    friend Container<Container<S>> make_double_container(const std::vector<std::vector<S>>&);
模板
朋友容器make_double_容器(const std::vector&);

您强制编译器从
容器的模板中找出
S
,然后它找出
S
的正确类型,即
int

显然,您可以让
的每一个特化都成为双容器的朋友:

template <typename U>
friend Container<Container<U>> make_double_container(const std::vector<std::vector<U>>&);
模板
朋友容器make_double_容器(const std::vector&);
如果你想在没有局部专业化或类似的情况下将友谊保持在最低限度,试试看

template <typename> struct extract {using type=void;};
template <typename U> struct extract<Container<U>> {using type=U;};
friend Container<Container<typename extract<T>::type>>
     make_double_container(const std::vector<std::vector<typename extract<T>::type>>&);
模板结构提取{using type=void;};
模板结构提取{using type=U;};
朋友容器
使双容器(const std::vector&);

这个问题在理论上很有趣。但是向量的向量有点邪恶,所以它基本上违背了目的。你的解决方案是可行的,但它会使例如
使双容器成为
容器的朋友。我正是想避免
f
成为
a
的朋友(第一个代码片段)。我认为您的第二个代码片段提供了“精确”的友谊,同时避免了编写许多专门的
f
的麻烦。聪明的把戏,+1!
 template<class S>
    friend Container<Container<S>> make_double_container(const std::vector<std::vector<S>>&);
template <typename U>
friend Container<Container<U>> make_double_container(const std::vector<std::vector<U>>&);
template <typename> struct extract {using type=void;};
template <typename U> struct extract<Container<U>> {using type=U;};
friend Container<Container<typename extract<T>::type>>
     make_double_container(const std::vector<std::vector<typename extract<T>::type>>&);