5

How can I make get a function in the enclosing scope that can access the private constructor of outer<T>::inner<U>?

template <typename T>
struct outer {
    template <typename U>
    class inner {
        inner() {}
    public:
        friend inner get(outer&) {
            return {};
        }
    };
};


int main() {
    outer<int> foo;
    outer<int>::inner<float> bar = get<float>(foo);
}

I have tried declaring it out of class by making inner have a template <typename V, typename W> friend inner<V> get(outer<W>&); but that didn't work either.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
user975989
  • 2,578
  • 1
  • 20
  • 38

1 Answers1

6

I have tried declaring it out of class by making inner have a template <typename V, typename W> friend inner<V> get(outer<W>&);

You need to declare the template function before the friend declaration, to tell the compiler that get is a template. E.g.

// definition of outer
template <typename T>
struct outer {

    // forward declaration of inner
    template <typename U>
    class inner;
};

// declaration of get
template <typename V, typename W> 
typename outer<W>::template inner<V> get(outer<W>&);

// definition of inner
template <typename T>
template <typename U>
class outer<T>::inner {
    inner() {}
    public:
    // friend declaration for get<U, T>
    friend inner<U> get<U>(outer<T>&);
};

// definition of get
template <typename V, typename W> 
typename outer<W>::template inner<V> get(outer<W>&) {
    return {};
}

LIVE

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • God that is gross. – user975989 Nov 05 '17 at 17:57
  • Actually, a friend definition is usually only accessible via ADL unless it has an out of class declaration prior. Is there a way to achieve the same effect here? – user975989 Nov 07 '17 at 02:06
  • @user975989 You mean you don't want to provide an out-of-class definition? – songyuanyao Nov 07 '17 at 02:18
  • Yeah I'm wondering if that's possible. Sorry I mean declaration NOT definition. https://stackoverflow.com/questions/8207633/whats-the-scope-of-inline-friend-functions – user975989 Nov 07 '17 at 02:20
  • @user975989 For your case (i.e. `get`) it's impossible. As you said, without a out-of-class declaration it can only be found by ADL. But `get` doesn't take parameter with type `inner`, ADL won't help either. (Yes I know you meant out-of-class declaration, it doesn't change the conclusion.) – songyuanyao Nov 07 '17 at 02:28