Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict template friends of a class

Consider the following code:

#include <iostream>

class S {
    static const int i = 42;
    template <class T>
    friend void f();
};

template <class T>
void f()
{
    std::cout << S::i << "\n";
}

int main() 
{
    f<int>();
    f<double>();
}

All I want here is to allow access to private part of a class S to f<int>, but not for f<double>. I.e. I want to get compiler error like 'i' is a private member of 'S' for f<double>() line.

How to achive this?

like image 558
αλεχολυτ Avatar asked Dec 25 '22 08:12

αλεχολυτ


1 Answers

The template instantiation is a function, so just name it: void f<int>().

You need a prior declaration, though:

[C++03: 11.4/9 | C++11/C++14: 11.3/11]: If a friend declaration appears in a local class (9.8) and the name specified is an unqualified name, a prior declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope. For a friend function declaration, if there is no prior declaration, the program is ill-formed. [..]

(This wasn't the case for the friend-inside-template-declaration that you had originally, because templates are looked up a little later in the parsing process.)

Here's the finished solution:

#include <iostream>

template <class T>
void f();

class S {
    static const int i = 42;
    friend void f<int>();
};

template <class T>
void f()
{
    std::cout << S::i << "\n";
}

int main() 
{
    f<int>();
    f<double>();
}

Now the only error is caused by the f<double>() call.

(live demo)

like image 144
Lightness Races in Orbit Avatar answered Dec 28 '22 08:12

Lightness Races in Orbit