can I have trait based friendship for a class

Discussion in 'C++' started by abir, Feb 27, 2008.

  1. abir

    abir Guest

    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
    abir, Feb 27, 2008
    #1
    1. Advertising

  2. abir

    Triple-DES Guest

    On 27 Feb, 07:39, abir <> wrote:
    > 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.
    Triple-DES, Feb 27, 2008
    #2
    1. Advertising

  3. abir

    abir Guest

    On Feb 27, 1:14 pm, Triple-DES <> wrote:
    > On 27 Feb, 07:39, abir <> wrote:
    >
    >
    >
    > > 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:

    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
    };
    abir, Feb 27, 2008
    #3
  4. abir

    Triple-DES Guest

    On 27 Feb, 09:47, abir <> wrote:
    > On Feb 27, 1:14 pm, Triple-DES <> wrote:
    >
    >
    >
    > > On 27 Feb, 07:39, abir <> wrote:

    >
    > > > 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:

    >
    > 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..


    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);
    Triple-DES, Feb 27, 2008
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Patrick Guio

    trait technique?

    Patrick Guio, Dec 18, 2004, in forum: C++
    Replies:
    7
    Views:
    362
    Jonathan Mcdougall
    Dec 21, 2004
  2. abir
    Replies:
    2
    Views:
    302
  3. Qi
    Replies:
    4
    Views:
    750
  4. Thufir
    Replies:
    2
    Views:
    87
    Thufir
    Nov 13, 2007
  5. Nephi Immortal
    Replies:
    2
    Views:
    172
    Nephi Immortal
    Feb 15, 2013
Loading...

Share This Page