简体   繁体   中英

friend method from a different namespace

I have the following situation. I have a class foo inside my own namespace my_lib :

namespace my_lib{

template<typename T>
class foo{
    T data;
public:
    // blah blah
};

}

I am trying to interface to another library that has its own namespace other_lib . I am putting this interface inside a wrapper namespace in my own my_lib . Specifically I for a copy method my_lib::wrapper::copy I need access to my_lib::foo::data so I need to implement the following:

namespace my_lib{
namespace wrapper{

template<typename T>
void copy(const foo<T>& my_foo, other_lib::foo<T>& other_foo)
{
    // copy my_foo.data to other_foo
}

}
}

to accomplish this my_lib::wrapper::copy method needs to be a friend of my_lib::foo class. I can accomplish this by series of forward declarations in foo.h

// forward declare other_lib::foo
namespace other_lib{
template<typename T>
class foo;
}

namespace my_lib{

// forward declare wrapper::copy
namespace wrapper{
template<typename T>
void copy(const foo<T>& my_foo, other_lib::foo<T>& other_foo);
}

template<typename T>
class foo{
    T data;

    friend void copy(const foo<T>& my_foo, other_lib::foo<T>& other_foo);
public:
    // blah blah
};

}

this works but I don't like it. For one thing it adds a lot of stuff to a file that is otherwise unrelated to other_lib and wrapper namespaces. Also, use of other library is optional in my code, but if someone includes foo.h they are going to see all sort of unrelated forward declarations and start to wonder why ...

How can I fix this design?

Syntactic tricks to get friend to work on other namespaces aside, the proper way is to fix your design. The interface of foo is simply not complete if it needs to grant a copy() function in some completely unrelated namespace friend access.

One way to go is to put copy() inside foo (and any other algorithm that users of foo need). When done right, this leads to a complete and usable class foo . Eg take a look at std::list which has it's own sort() member function to take advantage of the list implementation details. However, this can quickly lead to a bloated class interface for foo (just look at std::string ), so it's not recommended as a general rule.

Alternatively, you could provide a minimal set of data access member functions (preferably iterators, not handles to raw data) so that other classes can implement algorithms that work on foo . With a regular container (array, vector etc.) as data representation inside foo , this would be my recommendation for general use.

However, since your class foo has a tricky sparse matrix representation, you should probably try the algorithms-as-members-approach first.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM