NOTE: this post is different from this one: Declare non-template friend function for template class outside the class, so please read my question before marking it as duplicate.
I want to declare a non-template friend function inside a class template, and the arguments and return type of that friend function is unrelated to the template argument. How should I do that?
Please note it is different from that previous question because in that question, arguments and return type of that friend function is related to the template argument.
Example, adapted from that question above:
// class.h
#include <iostream>
using namespace std;
template <typename T>
struct B
{
T value;
int value2;
B() : value2(1) {}
friend void modify(const int&); // unrelated to T!
void printValue2() {
modify(value2);
cout << value2 << endl;
}
};
// define friend function foo() in a class.cpp file, not in the header
void modify(const int &v) { v = v * 2 + 1; } // HOW should I write it?
// main.cpp
int main() {
B<int> b;
b.printValue2();
return 0;
}
I know I can declare modify() outside this template class so it becomes a vanilla, ordinary function. But I want only this template class to have access to modify(). Alternatively, to achieve this goal of access control, I could define modify() to be a static method in this template class, but that would make the method a template method, forcing me to define it in the header.
Followup: if the friend approach above doesn't work, how should I achieve the two goals at the same time:
access control: only that class template can access modify()
be able to define modify() in a *.cpp file, rather in a header.
Accepted Answer:
To achieve the two goals above, don't abuse friendship.
The best practice is let the class template privately inherit a non-template base class, and in that base class declare common non-template methods that are unrelated to template arguments.
Therefore, you are able to define these methods in a separate *.cpp file, reducing the header's size.
You might use private inheritance instead of friendship:
// class.h
#include <iostream>
class B_helper
{
protected:
static void modify(int &v);
};
template <typename T>
struct B : private B_helper
{
T value;
int value2;
B() : value2(1) {}
void printValue2() {
modify(value2);
std::cout << value2 << std::endl;
}
};
// class.cpp
void B_helper::modify(int &v) { v = v * 2 + 1; }
You do it like this:
// class.cpp
void modify(const int &v) { v = v * 2 + 1; }
You are effectively abusing friendship, but ok. What this means is that you need to work around what it means to declare a function with friend: It is only visible through ADL! Now there is no way to refer to modify, because modify doesn't depend on B, so B's scope is never searched for a function named modify.
There is a work-around, but it's not pretty. You need to declare modify in every function where you use it. You could also declare it in global scope, but then everyone can call it. Alternatively, you can always declare it in a detail namespace (but this has the same issue a bit):
template<typename T>
void B<T>::printValue2() {
void modify(const int&);
modify(value2);
cout << value2 << endl;
}
As I said in the comments, friendship controls access to a class. As long as your function modify() is a standalone function, it cannot be befriended. As you want to call it from a template, it cannot be hidden it in a .cpp file either, but must be visible with the definition of the class template B and its member using modify().
One solution is to put modify as a static method in a auxiliary non-template class, which in turn befriends the template B<>.
// file foo.h (header)
namespace foo {
template<typename> class B; // forward declaration
class exclusive_for_B
{
template<typename T>
friend class B<T>;
static void modify(int&x) // must take int&, not const int&
{ x &= x+42; }
};
template<typename T>
class B
{
int val;
public:
...
void printvalue()
{
exclusive_for_B::modify(val); // access via friendship
std::cout << val << '\n';
}
};
}
Related
I created a class and I want to force anyone who's trying to construct an object, to use unique_ptr. To do that I thought of declaring the constructor protected and use a friend function that returns a unique_ptr. So here's an example of what I want to do:
template <typename T>
class A
{
public:
friend std::unique_ptr<A<T>> CreateA<T>(int myarg);
protected:
A(int myarg) {}
};
template <typename T>
std::unique_ptr<A<T>> CreateA(int myarg)
{
// Since I declared CreateA as a friend I thought I
// would be able to do that
return std::make_unique<A<T>>(myarg);
}
I did some reading on friend functions and I understood that a friend function provides access to private/protected members of an object of a class.
Is there anyway I can make my example work?
Even without friend functions, my goal is to make the CreateA the only way for someone to create an object.
EDIT
I change the code a bit. I didn't mention that my class takes one template parameter. That makes things more complex apparently.
You can do it this way :-
#include <iostream>
#include <memory>
using namespace std;
class A
{
int arg;
public:
friend unique_ptr<A> CreateA(int myarg);
void showarg() { cout<<arg; }
protected:
A(int myarg): arg(myarg) {}
};
unique_ptr<A> CreateA (int myarg)
{
return std::unique_ptr<A>(new A(myarg));
}
int main()
{
int x=5;
unique_ptr<A> u = CreateA(x);
u->showarg();
return 0;
}
Output :-
5
If you don't want to use friend function you can make the function static & call it like this :-
unique_ptr<A> u = A::CreateA(x);
EDIT :-
In reply to your edit I rewrote the program & it goes like this :-
#include <iostream>
#include <memory>
using namespace std;
template <typename T>
class A
{
T arg;
public:
static std::unique_ptr<A> CreateA(T myarg)
{
return std::unique_ptr<A>( new A(myarg) );
}
void showarg()
{
cout<<arg;
}
protected:
A(T myarg): arg(myarg) {}
};
int main()
{
int x=5;
auto u = A<int>::CreateA(x);
u->showarg();
return 0;
}
Simple & easy !!! But remember you cannot instantiate the object of A. Good Luck !!!
The other answers suggest using a static template function, which I agree is the best solution, because it is simpler.
My answer explains why your friend approach didn't work and how to use the friend approach correctly.
There are two problems in your original code. One is that make_unique is not actually a friend of A, so the call make_unique<A<T>>(myarg); does not have access to A's protected constructor. To avoid this , you can use unique_ptr<A<T>>(new A(myarg)) instead. Theoretically it would be possible to declare make_unique a friend but I'm not even sure of the right syntax for that.
The other issue is the template friends problem. Inside a class template, friend <function-declaration> actually declares a non-template friend.
The C++ FAQ suggests two possible workarounds. One of them is to define the friend function inline. However, in that case the function can only be found by argument-dependent lookup. But since the function does not take A<T> (or A<T> &) as argument, it can never be found this way. So this option is not viable to your situation -- it's more suited to operator overloading.
So the only fix is to declare (and optionally define) the template function before the class definition:
#include <memory>
template<typename T>
class A;
template <typename T>
std::unique_ptr<A<T>> CreateA(int myarg)
{
return std::unique_ptr<A<T>>{new A<T>(myarg)};
}
template <typename T>
class A
{
friend std::unique_ptr<A<T>> CreateA <> (int myarg);
// refers to existing template ^^
protected:
A(int myarg) {}
};
int main()
{
auto x = CreateA<int>(5);
}
Note: It is possible to declare CreateA where I have defined it, and put the function definition later. However, the code I have posted works -- despite A not being defined when new A<T>(myarg) appears in the source -- because CreateA is not instantiated until it is called, at which point A will be defined.
Create a static function that instantiates the protected constructor.
#include<iostream>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include <memory>
using namespace std;
template< typename T >
class A
{
public:
static void CreateA(int myarg, std::unique_ptr<A<T>>& objA, T t) {
std::unique_ptr<A<T>> objB(new A(myarg, t));
objA = std::move(objB);
}
protected:
A(int myarg, T t) {
m_t = t;
}
private:
T m_t;
};
int main() {
int myArg = 0;
std::unique_ptr<A<int>> anotherObjA;
A<int>::CreateA(myArg, anotherObjA, myArg);
return 0;
}
How could I make a function only seen by the function that calls it?
define the function I want to hide as private function is not enough, as it could still be seen by other public functions in the class.
Now I use lambda expression to define anonymous function inside function. Is there any better solution?
Aside from using a lambda (which you've rejected), you could implement your function in its own compilation unit, and code the supporting function in an anonymous namespace within that compilation unit.
But that supporting function would be outside the class, so you'd have to pass it all the parameters it needed. That could become unwieldly though no worse than a long lambda capture list.
You can use a function object. For example(you can compile this, even in C++03):
#include <iostream> // only for output
class foo{
int bar(){return 0;} // Only foo can see this
public:
int operator()(){
return bar();
}
};
class baz{
public:
foo do_foo;
};
int main(){
baz a;
std::cout << a.do_foo() << std::endl;
}
the method bar is only visible by a foo.
P.S.: If you need foo to access members of baz, make it a friend.
A simmilar approach to cassiorenan would be to use static class functions and friends.
Something like this:
void Boss();
class Worker {
static void Test(){ return;}
friend void Boss();
};
void Boss(){
Worker::Test();
}
Though why would you want to do this, I don't know.
It is possible to define function inside a function without lambdas. Just define a struct that contains required function. This approach is not much better than using lambda, but at least this is straightforward and works with older compilers too.
int func() {
struct {
int hiddenFunc() {
return 1;
}
} h;
int a = h.hiddenFunc() + h.hiddenFunc();
return a;
}
As a slight variation from cassiorenan's solution, you could use a class containing one public static function (the visible function) and one static private function that could only be called from there. To avoid creation of objects of that class, it is enough to put a private constructor.
EDIT:
Per cassiorenan's comment, I can see that OP really needs methods and not functions. In that case, I would still use a dedicated class in a anonymous namespace to ensure it is not visible from elsewhere (even if my example is single file ...) friend to the class really used. So in below example, bar is the business class that would have a method with an externally hidden implementation (here relay_method), and foo is dedicated to the hidden method called with a pointer to the real object. In real world, the whole anonymous namespace and the implementation of the hidden method should be in the implementation file bar.cpp.
That way, the real implementation function priv_func can only be called from a bar object through bar::relay_method() and foo::bar_func(bar &).
#include <iostream>
class bar;
namespace {
class foo {
private:
static int priv_func(int i) {
return i * i;
}
foo() {}
public:
// only useful if true functions were needed
/* static int pub_func(int i, int j) {
return priv_func(i) + priv_func(j);
}*/
static void bar_func(bar& b);
};
}
class bar {
int x;
int x2;
public:
bar(int i): x(i) {}
void relay_method() {
foo::bar_func(*this);
}
friend class foo;
int getX2() const {
return x2;
}
};
void foo::bar_func(bar& b) {
b.x2 = foo::priv_func(b.x);
}
using namespace std;
int main() {
/* int i = foo::pub_func(3,4);
cout << i << endl;
// foo::priv_func(2); error access to private member of class foo
// foo f; */
bar b(2);
b.relay_method();
cout << b.getX2() << endl;
return 0;
}
From a blog post Access to private members: Safer nastiness by Johannes Schaub - litb:
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// use
struct A {
A(int a):a(a) { }
private:
int a;
};
// tag used to access A::a
struct A_f {
typedef int A::*type;
friend type get(A_f);
};
template struct Rob<A_f, &A::a>;
int main() {
A a(42);
std::cout << "proof: " << a.*get(A_f()) << std::endl;
}
how get function can be call from a object since its not defined inside class A ?
EDIT:
I don't understand why get must have Tag as parameter instead of a.*get<A_f>()
=> ok it's due to ADL mechanism
You are not calling get from a! Actually what get return is a class pointer to a member inside A and type of it is int A::* so you need an instance of A to access that value.
For example let me play a little with your code:
struct A {
A(int a):a(a) { }
int b;
private:
int a;
};
void test() {
auto p = &A::b;
std::cout << a.*p << std::endl;
}
Did I call p from inside a? a does not have p, this is exactly what happened in your code, get function return &A::a and you use a to read its value! that's all, nothing is wrong and I think it will be compiled in all compilers.
One other question here is: Why C++ allow declaring template using private member of A. C++ standard say:
14.7.2p8 The usual access checking rules do not apply to names used to specify explicit instantiations. [Note: In particular, the template
arguments and names used in the function declarator (including
parameter types, return types and exception specifications) may be
private types or objects which would normally not be accessible and
the template may be a member template or member function which would
not normally be accessible.]
But if you try to instantiate or even typedef specified template then you get an error.
Let's modify your example slightly:
struct A {
private:
int a;
friend void f();
};
// Explicit instantiation - OK, no access checks
template struct Rob<A_f, &A::a>;
// Try to use the type in some way - get an error.
struct Rob<A_f, &A::a> r; // error
typedef struct Rob<A_f, &A::a> R; // error
void g(struct Rob<A_f, &A::a>); // error
// However, it's Ok inside a friend function.
void f() {
Rob<A_f, &A::a> r; // OK
typedef Rob<A_f, &A::a> R; // OK
}
It's legal because friend functions are always in the global scope, even if you implement them inside a class. In other words, this:
class A
{
friend void go() {}
};
is just a shortcut for:
class A
{
friend void go();
};
void go() {}
This is a known compiler bug in gcc and was fixed in a later release.
See-:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41437
Hi so I have a template class called Body, that takes a single sf::Drawable descendant as a template argument, and i'm trying to overide the Render() function only for the case that the template argument is a sf::Shape.
How do i do this in a non-inline way? The code works when I define the function inside the class, automatically making it inline, but I get link errors (multiple Render symbols detected) when I define the function in a seperate .cpp file.
If it helps here's the code that produces an error:
// in the header file
template<typename drawable= void>
class Body : public sf::Drawable
{
void Render(){Do_Something();
}
template <>
class Body<Shape> : public sf::Drawable
{
void Render();
}
// in the cpp file
void Body<Shape>::Render()
{
Do_Something_Else();
}
You mean like this?
template <typename T>
struct Foo {
int frob() const;
};
// Note: Member function specializations do not require
// full class specializations.
template <typename T>
int Foo<T>::frob() const { return 42; }
template <>
int Foo<float>::frob() const { return 0xbeef; }
#include <iostream>
int main () {
std::cout << Foo<int>().frob() << '\n';
std::cout << Foo<float>().frob() << '\n';
}
Note that the specializations need to be visible where you use them, so in most cases, you have to put them in the header, too.
This is purely a theoretical question, I know that if someone declares a method private, you probably shouldn't call it. I managed to call private virtual methods and change private members for instances, but I can't figure out how to call a private non-virtual method (without using __asm). Is there a way to get the pointer to the method? Are there any other ways to do it?
EDIT: I don't want to change the class definition! I just want a hack/workaround. :)
See my blog post. I'm reposting the code here
template<typename Tag>
struct result {
/* export it ... */
typedef typename Tag::type type;
static type ptr;
};
template<typename Tag>
typename result<Tag>::type result<Tag>::ptr;
template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
/* fill it ... */
struct filler {
filler() { result<Tag>::ptr = p; }
};
static filler filler_obj;
};
template<typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;
Some class with private members
struct A {
private:
void f() {
std::cout << "proof!" << std::endl;
}
};
And how to access them
struct Af { typedef void(A::*type)(); };
template class rob<Af, &A::f>;
int main() {
A a;
(a.*result<Af>::ptr)();
}
#include the header file, but:
#define private public
#define class struct
Clearly you'll need to get around various inclusion guards etc and do this in an isolated compilation unit.
EDIT:
Still hackish, but less so:
#include <iostream>
#define private friend class Hack; private
class Foo
{
public:
Foo(int v) : test_(v) {}
private:
void bar();
int test_;
};
#undef private
void Foo::bar() { std::cout << "hello: " << test_ << std::endl; }
class Hack
{
public:
static void bar(Foo& f) {
f.bar();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Foo f(42);
Hack::bar(f);
system("pause");
return 0;
}
It can be called if a public function returns the address of the private function, then anyone can use that address to invoke the private function.
Example,
class A
{
void f() { cout << "private function gets called" << endl; }
public:
typedef void (A::*pF)();
pF get() { return &A::f; }
};
int main()
{
A a;
void (A::*pF)() = a.get();
(a.*pF)(); //it invokes the private function!
}
Output:
private function gets called
Demo at ideone : http://www.ideone.com/zkAw3
The simplest way:
#define private public
#define protected public
Followup on T.E.D.'s answer: Don't edit the header. Instead create your own private copy of the header and insert some friend declarations in that bogus copy of the header. In your source, #include this bogus header rather than the real one. Voila!
Changing private to public might change the weak symbols that result from inlined methods, which in turn might cause the linker to complain. The weak symbols that result from inline methods will have the same signatures with the phony and real headers if all that is done is to add some friend declarations. With those friend declarations you can now do all kinds of evil things with the class such as accessing private data and calling private members.
Addendum
This approach won't work if the header in question uses #pragma once instead of a #include guard to ensure the header is idempotent.
You have friend classes and functions.
I know that if someone declares a method private, you probably
shouldn't call it.
The point is not 'you shouldn't call it', it's just 'you cannot call it'. What on earth are you trying to do?
Call the private method from a public function of the same class.
Easiest way to call private method (based on previous answers but a little simpler):
// Your class
class sample_class{
void private_method(){
std::cout << "Private method called" << std::endl;
}
};
// declare method's type
template<typename TClass>
using method_t = void (TClass::*)();
// helper structure to inject call() code
template<typename TClass, method_t<TClass> func>
struct caller{
friend void call(){
TClass obj;
(obj.*func)();
}
};
// even instantiation of the helper
template struct caller<sample_class,&sample_class::private_method>;
// declare caller
void call();
int main(){
call(); // and call!
return 0;
}
Well, the obvious way would be to edit the code so that it is no longer private.
If you insist on finding an evil way to do it...well...with some compilers it may work create your own version of the header file where that one method is public instead of private. Evil has a nasty way of rebounding on you though (that's why we call it "evil").
I think the closest you'll get to a hack is this, but it's not just unwise but undefined behaviour so it has no semantics. If it happens to function the way you want for any single program invocation, then that's pure chance.
Define a similar class that is the same apart from the function being public.
Then typecast an object with the private function to one with the public function, you can then call the public function.
If we are speaking of MSVC, I think the simplest way with no other harm than the fact of calling a private method itself is the great __asm:
class A
{
private:
void TestA () {};
};
A a;
__asm
{
// MSVC assumes (this) to be in the ecx.
// We cannot use mov since (a) is located on the stack
// (i.e. [ebp + ...] or [esp - ...])
lea ecx, [a]
call A::TestA
}
For GCC it can be done by using mangled name of a function.
#include <stdio.h>
class A {
public:
A() {
f(); //the function should be used somewhere to force gcc to generate it
}
private:
void f() { printf("\nf"); }
};
typedef void(A::*TF)();
union U {
TF f;
size_t i;
};
int main(/*int argc, char *argv[]*/) {
A a;
//a.f(); //error
U u;
//u.f = &A::f; //error
//load effective address of the function
asm("lea %0, _ZN1A1fEv"
: "=r" (u.i));
(a.*u.f)();
return 0;
}
Mangled names can be found by nm *.o files.
Add -masm=intel compiler option
Sources: GCC error: Cannot apply offsetof to member function MyClass::MyFunction
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
After reading Search for an elegant and nonintrusive way to access private methods of a class, I want to sum up an ideal way since no one else has pasted it here:
// magic
//
template <typename Tag, typename Tag::pfn_t pfn>
struct tag_bind_pfn
{
// KEY: "friend" defines a "pfn_of" out of this template. And it's AMAZING constexpr!
friend constexpr typename Tag::pfn_t pfn_of(Tag) { return pfn; }
};
// usage
//
class A
{
int foo(int a) { return a; }
};
struct tag_A_foo
{
using pfn_t = int (A::*)(int);
// KEY: make compiler happy?
friend constexpr typename pfn_t pfn_of(tag_A_foo);
};
// KEY: It's legal to access private method pointer on explicit template instantiation
template struct tag_bind_pfn<tag_A_foo, &A::foo>;
inline static constexpr const auto c_pfn_A_foo = pfn_of(tag_A_foo{});
#include <cstdio>
int main()
{
A p;
auto ret = (p.*(c_pfn_A_foo))(1);
printf("%d\n", ret);
return 0;
}