Templates

  • Thread starter Massimiliano Alberti
  • Start date
M

Massimiliano Alberti

Can I do something like:

template <int* Z>
class Y
{
DoStuff() { *Z = 5; }

};

class X : public Y<&X::p>
{
int p;
};

--- bye
 
R

Rob Williscroft

Massimiliano Alberti wrote in
Can I do something like:

template <int* Z>
class Y
{
DoStuff() { *Z = 5; }

};

class X : public Y<&X::p>
{
int p;
};

No &X::p has type int (X::*) not int *, also X::p hasn't been declared
at the point you use it.

template < typename Derived >
struct Y
{
void DoStuff() { static_cast< Derived * >( this )->p = 5; }
};

struct X : Y< X >
{
};

HTH.

Rob.
 
J

Jeff Schwab

Rob said:
Massimiliano Alberti wrote in



No &X::p has type int (X::*) not int *, also X::p hasn't been declared
at the point you use it.

template < typename Derived >
struct Y
{
void DoStuff() { static_cast< Derived * >( this )->p = 5; }
};

struct X : Y< X >
{
};


Except that, in your example, X no longer has an element called p. :)
Here's the same functionality, without any casting or CRTP.

struct Y
{
void do_stuff( ) { p( 5 ); }
protected:
virtual void p( int ) =0;
};

struct X: Y
{
int p( ) const { return m_p; }
protected:
void p( int i ) { m_p = i; }
private:
int m_p;
};

#include <iostream>

int main( )
{
X x;

x.do_stuff( );

std::cout << x.p( ) << std::endl;
}
 
V

Victor Bazarov

Massimiliano Alberti said:
Can I do something like:

template <int* Z>
class Y
{
DoStuff() { *Z = 5; }

Did you mean

void DoStuff() { *Z = 5; }

?
};

class X : public Y<&X::p>
{
int p;
};

No, this is not allowed. Only addresses of objects with external linkage
are allowed. You're trying to use a _pointer_to_member_ expression where
a pointer to int is expected, and also (while incorrectly syntactically)
you're trying to use an address of an object that has no linkage (a data
member has no linkage if it's non-static).

V
 
R

Rob Williscroft

Victor Bazarov wrote in
No, this is not allowed. Only addresses of objects with external
linkage are allowed. You're trying to use a _pointer_to_member_
expression where a pointer to int is expected, and also (while
incorrectly syntactically) you're trying to use an address of an
object that has no linkage (a data member has no linkage if it's
non-static).

#include <iostream>
#include <ostream>

template < typename T, typename C, T C::*member >
struct X
{
static T test( C * c) { return c->*member; }
};

struct Y
{
int p;
};

typedef X< int, Y, &Y::p > XY;

template < char * p >
struct PP
{
char a() { return *p; }
};

char array[1] = {'a'};

typedef PP< array > PP_array;

int main()
{
using namespace std;

Y y = { 10 };
cerr << XY::test( &y ) << '\n';

cerr << PP_array().a() << '\n';
}

IIUC all that matters here is that Y has external linkage.
i.e. &Y::p is a constant whose value is unique as its based upon
Y's external linkage.

I think something similar goes on above with PP, PP's paramiter p
is a char * const that is unique in that it is based on array a
char [1] with external linkage.

Rob.
 
M

Massimiliano Alberti

No &X::p has type int (X::*) not int *, also X::p hasn't been declared
at the point you use it.

Clearly I can't simply writebecause p is not defined at this point... So I can't do what I was thinking
of with templates... mmmh... Ok... :-(

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,427
Latest member
HildredDic

Latest Threads

Top