can I have trait based friendship for a class

A

abir

Hi, I have a class which once created , can not be changed. However as
it has a few states, which need to be set with a few function call, I
thought to activate(enable) those functions only a certain trait is
present in the caller class.

eg,
class Stroke{
private:
typedef std::pair<uint32_t,uint32_t> PointPair;
PointPair points_;
StrokeType type_; ///< StrokeType is an enum;
Dir dir_; //< another enum
std::size_t drawingID_ ; //some stroke id
...
public:
Stroke(Drawing& d,PointPair& points, std::size_t id);
void setDir(Dir d);
};

now my constructor sets a few fields, when the class is created.
The remaining things i want to set only using some classes, which has
certain traits.
Like I want a class which has a trait can_set_dir, has setDir enabled
(using boost::enable_if or equivalent), But the class which doesn't
have the trait can't call the function (it will be removed from the
definition).
This is kind of selective friendship I want to achieve, without using
friend keyword which is intrusive in nature.

Is it possible to make this kind of selective function calling based
on trait ? ( I am free to modify signature of setDir for that purpose)

thanks
abir
 
T

Triple-DES

Hi, I have a class which once created , can not be changed. However as
it has a few states, which need to be set with a few function call, I
thought to activate(enable) those functions only a certain trait is
present in the caller class.

eg,
class Stroke{
  private:
    typedef std::pair<uint32_t,uint32_t> PointPair;
    PointPair points_;
    StrokeType type_; ///< StrokeType is an enum;
    Dir dir_; //< another enum
    std::size_t drawingID_ ; //some stroke id
    ...
   public:
    Stroke(Drawing& d,PointPair& points, std::size_t id);
   void setDir(Dir d);

};

now my constructor sets a few fields, when the class is created.
The remaining things i want to set only using some classes, which has
certain traits.
Like I want a class which has a trait can_set_dir, has setDir enabled
(using boost::enable_if or equivalent), But the class which doesn't
have the trait can't call the function (it will be removed from the
definition).
This is kind of selective friendship I want to achieve,  without using
friend keyword which is intrusive in nature.

Is it possible to make this kind of selective function calling based
on trait ? ( I am free to modify signature of setDir for that purpose)

It isn't possible with 'natural' syntax. You have to pass the caller
class to the function somehow. If this is acceptable:

template<typename Caller>
class Stroke
{
// ...
};

It would be possible to "disable" functions for a specific caller at
compile time.
 
A

abir

It isn't possible with 'natural' syntax. You have to pass the caller
class to the function somehow. If this is acceptable:
It's true, i can pass the caller.
template<typename Caller>
class Stroke
{
// ...

};

It would be possible to "disable" functions for a specific caller at
compile time.

I can't make Stroke class a template, as that will make many
incompatible Stroke object for each caller.
However what I am thinking is to have a function like
class Stroke{
public:
template<typename Caller>
setDir(Dir d, boost::enable_if_c<Caller::cal_change_dir>) ... kind of
thing.

thanks for reply..
abir
};
 
T

Triple-DES

It's true, i can pass the caller.




I can't make Stroke class a template, as that will make many
incompatible Stroke object for each caller.
However what I am thinking is to have a function like
class Stroke{
public:
template<typename Caller>
setDir(Dir d, boost::enable_if_c<Caller::cal_change_dir>) ... kind of
thing.

thanks for reply..

I understand. This will work, but it may not be the most elegant
approach:

class Stroke
{
public:
typedef int Dir;
template<typename Caller>
void setDir(Dir d, const Caller* c)
{
// CT is the traits class
setDir< CT<Caller>::can_set_dir>(d);
}
private:
template<bool enabled>
void setDir(Dir d);
template<>
void setDir<true>(Dir d) { /* actual set dir code */ };
};

Caller code would look like this:

Stroke s;
s.setDir(42, this);
 

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

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top