Declaring set of member functions as friend by using template - c++

Given the following code:
class A;
struct B {
static void doIt(A* pa);
};
struct C {
static void doIt(A* pa);
};
class A {
int i = 9;
// below works but requires a line per each type
friend void B::doIt(A* pa);
friend void C::doIt(A* pa);
// the below however doesn't work
// template<typename T>
// friend void T::doIt(A* pa);
// (gcc error: member 'void T::doIt(A*)' declared as friend before type 'T' defined)
// (clang just ignores the above and the error is on accessing A::i in B and C)
};
void B::doIt(A* pa) {
cout << pa->i << endl;
}
void C::doIt(A* pa) {
cout << pa->i *2 << endl;
}
int main() {
A a;
B::doIt(&a);
C::doIt(&a);
}
Is it possible to replace the multiple friend declarations to allow all void T::doIt(A* pa) methods access the private members of A?
Trying to instantiate B and C above A doesn't help.

Not exactly what do you asked but... if you templatize the B, C, etc. structs, you can get something similar.
#include <iostream>
class A;
template <std::size_t>
struct X
{ static void doIt(A* pa); };
class A
{
int i = 9;
template <std::size_t I>
friend void X<I>::doIt (A* pa);
};
template <>
void X<0U>::doIt(A* pa)
{ std::cout << pa->i << std::endl; }
template <>
void X<1U>::doIt(A* pa)
{ std::cout << pa->i * 2 << std::endl; }
template <>
void X<2U>::doIt(A* pa)
{ std::cout << pa->i * 3 << std::endl; }
using B = X<0U>;
using C = X<1U>;
using D = X<2U>;
int main() {
A a;
B::doIt(&a);
C::doIt(&a);
D::doIt(&a);
}

I believe something similar to what you desire can be done using CRTP and private/protected virtual inheritance. The code below is only demonstration and definitely needs some work e.g. to not to involve template method friendship:
#include <iostream>
using namespace std;
class base {
protected:
int i = 9;
};
template <class F>
class crtp_base: virtual base { // private inheritance!
template <class T>
friend void F::doIt(T*);
};
template <class... AllF>
struct crtp_bases: crtp_base<AllF>... { };
struct B {
template <class T>
static void doIt(T* pa);
};
struct C {
template <class T>
static void doIt(T* pa);
};
class A: public crtp_bases<B, C> {
};
template <class T>
void B::doIt(T* pa) {
cout << pa->i << endl;
}
template <class T>
void C::doIt(T* pa) {
cout << pa->i * 2 << endl;
}
int main() {
A a;
B::doIt(&a);
//cout << a.i << endl; // error i is private member of 'base'
}
[live demo]

I see no direct way, but one work-around could be declaring one class with several static methods (instead of several classes with one static method) and then declaring this class as friend, like:
...
struct D {
static void doItB(A* pa);
static void doItC(A* pa);
};
class A {
...
friend struct D;
...
};
void D::doItB(A* pa) {
cout << pa->i << endl;
}
...
D::doItB(&a);
D::doItC(&a);
...

Related

how to add member-variable for a specialized version of a template class?

I have a template class, and at least 95% codes of it is same for all types of the template-parameter, unless a member-variable and a function should be added for one specialization.
The sample I want to get is following:
template <typename T>
class AClass {
private:
T payLoad;
public:
AClass( const T& crp_payload ) : payLoad( crp_payload ) {};
void showMe() {
cout << "Common showMe:" << payLoad << endl;
};
/*
* A lot of functions same for all specializations go here.
* I absolutely don't want to implement respectively them for
* every specializations!
*/
// specializing for int ----------------------------
// dedicated function
template <int>
void showPayload() {
cout << "AClass<int>::showPayload:" << payLoad << endl;
};
// dedicated variable, but following code can not be compiled!
template <int>
int otherPayload;
};
int main() {
AClass<int> iac( 123 );
iac.showMe();
iac.showPayload();//can not pass the compiling!
AClass<float> fac(456);
fac.showMe();
return 0;
};
My questions:
How to add merely "otherPayload" variable without re-coding entire
AClass<int>?
How to call showPayload() sinc I get a error msg when I
do it in main() as above.
Is there no way only by specializing to "revise/supplement" some
members to a class without totally re-implement it?
One possible way would be the good old inheritance:
template<class T> struct Extra {};
template<> struct Extra<int> {
int extraPayload;
void showPayload();
};
template<class T> class Class: public Extra<T> {
void showMe();
};
template<> void Class<int>::showMe() { showPayload(); }
All the specialization-specific parts are extracted in a separate class, and common methods are specialized as needed.
I think you can simply do normal specialization of the template-class:
#include <iostream>
#include <iomanip>
template <typename T>
class BaseClass
{
protected:
T payLoad;
public:
BaseClass(const T& crp_payload)
: payLoad( crp_payload )
{ }
void showMe() {
std::cout << "Common showMe:" << payLoad << std::endl;
}
/*
* A lot of functions same for all specializations go here.
* I absolutely don't want to implement respectively them for
* every specializations!
*/
};
template <typename T>
class AClass
: public BaseClass<T>
{
public:
AClass( const T& crp_payload )
: BaseClass<T>(crp_payload)
{ }
};
// specializing for int ----------------------------
template<>
class AClass<int>
: public BaseClass<int>
{
public:
AClass( int crp_payload )
: BaseClass(crp_payload)
{ }
// dedicated function
void showPayload() {
std::cout << "AClass<int>::showPayload:" << payLoad << std::endl;
}
private:
int otherPayload;
};
int main() {
AClass<int> iac( 123 );
iac.showMe();
iac.showPayload();//can not pass the compiling!
AClass<float> fac(456);
fac.showMe();
return 0;
}

Hacking private data using c++

Clarification: This question originally came from a challenge I thought of, and isn't connect with programming for real systems.
Suppose I have a class, that I know its' architecture which I can't change, and I don't want to inherit it, but I do want to get access to its' private data and functions. How can I do it?
Suppose my class looks like this one:
class A {
public:
int v = 89;
private:
int a = 5;
virtual void function(int a, int b) {
cout << a << " " << b << endl;
}
};
a while ago stumbled upon a neat template trick to do this on this blog: http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html
Do NOT use this in any production code, it is just a educational example !!!
it takes basically leverage of the "private" being ignored on some part of template initialization
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;
usage: take following struct:
struct A {
private:
void f() {
std::cout << "proof!" << std::endl;
}
};
create your "robber"
struct Af { typedef void(A::*type)(); };
template class rob<Af, &A::f>;
use it:
int main()
{
A a;
(a.*result<Af>::ptr)();
return 0;
}
A less risky hack will be to make your function/class a friend of the class if you are allowed to modify just the header file.
// Add
class HackA;
class A {
public:
// Add
friend class HackA;
int v = 89;
private:
int a = 5;
virtual void function(int a, int b) {
cout << a << " " << b << endl;
}
};
Now you can use:
class HackA {
public:
int number(A const& a) { return a.v; }
int another_number(A const& a) { return a.a; }
void target_function(A& a, int number, int another_one)
{
a.function(number, another_one);
}
};
int main()
{
A a;
HackA hacker
cout << hacker.number(a) << " " << hacker.another_number(a) << endl;
hacker.target_function(a, 9, 3);
return 0;
}

C++ factoring tempate methods specialization of a template class, is that possible?

I have a template method inside a template class.
I read that a method can not be specialized without specialize the class before.
But I want to factorize some of theses methods, is it possible ?
Example :
class One {
public:
static const int number = 1;
};
class Two {
public:
static const int number = 2;
};
template<typename num> class A {
private:
num n;
public:
template<typename type>
void multiplyBy(); // by 1 if <int> or 1,5 if <float>
}; // A
template<> template<> void A<One>::multiplyBy<int>() {
std::cout << 1.0*n.number << std::endl;
}
template<> template<> void A<One>::multiplyBy<float>() {
std::cout << 1.5*n.number << std::endl;
}
template<> template<> void A<Two>::multiplyBy<int>() {
std::cout << 1.0*n.number << std::endl;
}
template<> template<> void A<Two>::multiplyBy<float>() {
std::cout << 1.5*n.number << std::endl;
}
int main() {
A<One> aOne;
A<Two> aTwo;
aOne.multiplyBy<int>(); // 1
aOne.multiplyBy<float>(); // 1.5
aTwo.multiplyBy<int>(); // 2
aTwo.multiplyBy<float>(); // 3
return 0;
}
A stackoverflow related question : C++ specialization of template function inside template class
In particular this comment : C++ specialization of template function inside template class
Have I to deduct than there is no way to factorize multiplyBy(), for one for int and an other for float ?
As english is not my natural language maybe I miss something simple, maybe a workaround with partial-specialization.
Edit : put A::n in private to match even better my problem.
You might use tag dispatching:
#include <iostream>
class One {
public:
static const int number = 1;
};
class Two {
public:
static const int number = 2;
};
template<typename num>
class A {
public:
num n;
private:
template<typename> struct Tag {};
void multiplyBy(Tag<int>) {
std::cout << 1.0*n.number << std::endl;
}
void multiplyBy(Tag<float>) {
std::cout << 1.5*n.number << std::endl;
}
public:
template<typename type>
void multiplyBy() {
multiplyBy(Tag<type>());
}
};
int main() {
A<One> aOne;
A<Two> aTwo;
aOne.multiplyBy<int>(); // 1
aOne.multiplyBy<float>(); // 1.5
aTwo.multiplyBy<int>(); // 2
aTwo.multiplyBy<float>(); // 3
return 0;
}
But I want to factorize some of theses methods, is it possible ?
You probably know that you cannot use:
template<> template<> void A<One>::multiplyBy<int>() {
std::cout << 1.0*n.number << std::endl;
}
without specializing A<One>.
You can do something along the lines of:
#include <iostream>
class One {
public:
static const int number = 1;
};
class Two {
public:
static const int number = 2;
};
template<typename num, typename type = int> struct MultiplyBy {
static void doit(num n)
{
std::cout << 1.0*n.number << std::endl;
}
};
template<typename num> struct MultiplyBy<num, float> {
static void doit(num n)
{
std::cout << 1.5*n.number << std::endl;
}
};
template<typename num> class A {
public:
num n;
template<typename type>
void multiplyBy()
{
MultiplyBy<num, type>::doit(n);
}
};
int main() {
A<One> aOne;
A<Two> aTwo;
aOne.multiplyBy<int>(); // 1
aOne.multiplyBy<float>(); // 1.5
aTwo.multiplyBy<int>(); // 2
aTwo.multiplyBy<float>(); // 3
return 0;
}

C++11 call member function on template parameter pack of base classes if present

I have checked questions that are similar. This is close, but not a duplicate.
In essence I want to call a function on a parameter pack of base classes if present. I have a C++11 way of doing this that works, but it does not feel satisfactory to me.
Can someone offer a better [i.e. better performance and less boilerplate code]:
source code:
#include <iostream>
#include <type_traits>
using namespace std;
// a class initialised with an int that can't do it
struct A
{
A(int a) : _a(a) { }
void report() const { std::cout << _a << std::endl; }
private:
int _a;
};
// a class initialised with a string that can do it
struct B
{
B(std::string s) : _b (move(s)) { }
void report() const { std::cout << _b << std::endl; }
void do_it() { std::cout << "B did it with " << _b <<"!" << std::endl; }
private:
string _b;
};
// a class initialised with an int that can do it
struct D
{
D(int d) : _d(d) { }
void report() const { std::cout << _d << std::endl; }
void do_it() { std::cout << "D did it with " << _d <<"!" << std::endl; }
private:
int _d;
};
// a class initialised with a string that can't do it
struct E
{
E(std::string s) : _e(move(s)) { }
void report() const { std::cout << _e << std::endl; }
private:
string _e;
};
// a function enabled only if T::do_it is a member function pointer
// the bool is there just to make this function more attractive to the compiler
// than the next one, below
template<class T>
auto do_it(T& t, bool)
-> typename std::enable_if<std::is_member_function_pointer<decltype(&T::do_it)>::value, void>::type
{
t.do_it();
}
// a catch-all function called when do_it<T> is not valid
// the ... is less attractive to the compiler when do_it<T>(T&, bool) is available
template<class T>
void do_it(T& t, ...)
{
}
// a compound class derived from any number of classes - I am so lazy I work hard at
// being lazy.
template<class...Templates>
struct C : public Templates...
{
// construct from a parameter pack of arbitrary arguments
// constructing each base class with one argument from the pack
template<class...Args>
C(Args&&...args)
: Templates(std::forward<Args>(args))...
{
}
// private implementation of the dispatch mechanism here...
private:
// this will call ::do_it<T>(T&, bool) if T::do_it is a member function of T, otherwise
// calls ::do_it<T>(T&, ...)
template<class T>
void may_do_it()
{
::do_it(static_cast<T&>(*this), true);
}
// calls may_do_it for the last class in the parameter pack
template<typename T1>
void multi_may_do_it()
{
may_do_it<T1>();
}
// general case for calling do_it on a parameter pack of base classes
template<typename T1, typename T2, typename...Rest>
void multi_may_do_it()
{
may_do_it<T1>();
multi_may_do_it<T2, Rest...>();
}
// calls may_do_it for the last class in the parameter pack
template<typename T1>
void multi_report() const
{
static_cast<const T1&>(*this).report();
}
// general case for calling do_it on a parameter pack of base classes
template<typename T1, typename T2, typename...Rest>
void multi_report() const
{
static_cast<const T1&>(*this).report();
multi_report<T2, Rest...>();
}
// the functions we actually wish to expose here...
public:
// disptach T::do_it for each valid T in base class list
void do_it() {
multi_may_do_it<Templates...>();
}
// dispatch T::report, which must exist for each base class
void report() const {
cout << "-- all base classes reporting:" << endl;
multi_report<Templates...>();
cout << "-- all base classes reported" << endl;
}
};
int main()
{
C<A,B, D, E> c(10, "hello", 7, "goodbye");
c.report(); // all base classes must report
c.do_it(); // all base classes that can do_it, must.
return 0;
}
output:
Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
Executing the program....
$demo
-- all base classes reporting:
10
hello
7
goodbye
-- all base classes reported
B did it with hello!
D did it with 7!
I think this is about as boilerplate-free as you can make it.
// a function enabled only if T::do_it is a member function pointer
template<class T>
auto do_it(T* t)
-> typename std::enable_if<std::is_member_function_pointer<decltype(&T::do_it)>::value, void>::type
{
t->do_it();
}
// a catch-all function called when do_it<T> is not valid
// the const void * is less attractive to the compiler when do_it<T>(T*) is available
template<class T>
void do_it(const void *)
{
}
// a compound class derived from any number of classes - I am so lazy I work hard at
// being lazy.
template<class...Templates>
struct C : public Templates...
{
//constructor omitted
private:
using expander = int[];
public:
// disptach T::do_it for each valid T in base class list
void do_it() {
(void) expander{ 0, (::do_it<Templates>(this), 0)...};
}
// dispatch T::report, which must exist for each base class
void report() const {
cout << "-- all base classes reporting:" << endl;
(void) expander{ 0, (Templates::report(), 0)...};
cout << "-- all base classes reported" << endl;
}
};
Demo.

Friend Function calling Static Members of Derived Classes. Not getting expected output

My first post here :)
I am having a problem with the following C++ code. I have an ABC class A, and two derived classes B and C. All of them have a static member called id:
using std::cout;
class A
{
private:
friend int bar(A& a);
static const int id = 1;
virtual void foo() = 0;
};
class B : public A
{
private :
friend int bar(A& a);
static const int id = 2;
void foo() { /*Do something*/ }
};
class C : public A
{
private:
friend int bar(A& a);
static const int id = 3;
void foo() { /*Do something*/ }
};
int bar(A& a)
{
return a.id;
}
int main()
{
B b;
C c;
cout << bar(b) << "\n";
cout << bar(c) << "\n";
return 0;
}
I was expecting this code to print out 2 and 3 - rather it prints out 1 and 1 (bar() is always using A::id). What am I doing wrong? Any ideas?
Based on the comments below, this the final code I am using. It works, but would love to hear more thoughts :)
#include <iostream>
using std::cout;
class A
{
private:
virtual void foo() = 0;
};
class B : public A
{
private:
template <typename T>
friend int bar(T& t);
static const int id = 2;
void foo() { /*do something*/ }
};
class C : public A
{
private:
template <typename T>
friend int bar(T& t);
static const int id = 3;
void foo() { /*do something*/ }
};
template <typename T>
int bar(T& t)
{
return t.id;
}
int main()
{
B b;
C c;
cout << bar(b) << "\n";
cout << bar(c) << "\n";
return 0;
}
a.id will be defined at compile-time as A::id. You would need to define a virtual member (non-static) function in class A and have it overridden in B and C to return their respective ids and call this function in bar.
Is there any way to avoid writing int foo() { return id; } for all the derived classes?
Yes, using templates. For example:
template <typename T>
int foo (T& x)
{
return x.id;
}
However, if id is private, this doesn't reduce the code by all that much.