Can friend class be declared conditionally in C++03?

前端 未结 5 1390
半阙折子戏
半阙折子戏 2021-01-19 02:54

I want to declare a friend class only if some (compile-time) condition is true. For example:

// pseudo-C++
class Foo {
    if(some_compile_time_condition) {
         


        
相关标签:
5条回答
  • 2021-01-19 03:12

    Use friend std::conditional<C, friendclass, void>::type; where C is your condition. A nonclass type friend will be ignored.

    The conditional template is easily implemented in C++03. However since C++03 does not support typedef friends you need to use the following syntax there

    namespace detail { class friendclass {}; }
    
    class Foo {
      friend class std::conditional<C, 
        friendclass, detail::friendclass>::type::friendclass;
    };
    

    Note that the detail dummy class name needs to match the name of the potential friend in this workaround.

    0 讨论(0)
  • 2021-01-19 03:12

    I think you take 1 preprocessor and write your source code inside that.

    bool flag = false;
    #ifdef _MY_FRIEND_
        friend class sample
        flag = true;
    #endif
    
    if (flag)
    {
     ...
     ...
     ...
    }
    

    class Foo {
    #ifdef _MY_FRIEND_
        friend class Bar;
    #endif
    }
    

    };

    Here _MY_FRIEND_ is a preprocessor and if you add that preprocessor then at compile time your class Bar will be the friend class...you can use that preprocssor any where when you want to need class Bar as a friend class.other wise compile without the preprocessor then it wont allow u to add Bar as a friend class of Foo

    Please correct me if i understood the question wrong.

    0 讨论(0)
  • 2021-01-19 03:26

    Note: Johannes has pretty much nailed it. In '03 you cannot befriend a typedef - but if you know you have a class, then you can refer to it's injected class name.

    Johannes' answer also has the benefit of using standard library functionality which too is always a good thing.

    #define some_compile_time_condition 0
    
    class Foo;
    
    template <int Condition> class  TestCondition {
    private:
      friend class Foo;
      struct Type {
        struct Bar;
      };
    };
    
    template <> class TestCondition<1> {
    public:
      typedef Bar Type;
    };
    
    struct Bar
    {
    public:
      void foo (Foo &);
    };
    
    class Foo {
    private:
      friend struct TestCondition< some_compile_time_condition >::Type::Bar;
      int m_i;
    };
    
    void Bar::foo (Foo & foo)
    {
      foo.m_i = 0;
    }
    

    It's still different to the requirement in that Foo always has a friend, but the befriended class changes based on the value of the option.

    An interesting side question is whether it is an ODR violation to have versions of Foo both with and without some_compile_time_condition set to 1.

    0 讨论(0)
  • 2021-01-19 03:30

    [class.friend]/3 tells this :

    A friend declaration that does not declare a function shall have one of the following forms:
    friend elaborated-type-specifier ;
    friend simple-type-specifier ;
    friend typename-specifier ;

    therefore it is not possible to conditionally declare friends of a class, without a macro.

    0 讨论(0)
  • 2021-01-19 03:35

    It seems, unfortunately, not possible within the C++ compiler: ie, it seems that only the preprocessor may help here. Note: Johannes has a proposal, so there is hope!

    However I would note that:

    • friendship does not require you to actually use it
    • friendship is a pure compile-time construct (like access specifiers) and does not incur any runtime penalty on any major compiler

    there is no reason not to have unconditional friendship, but only use it if some conditions (static or dynamic) are met.

    Note: in the future, this is something that the static_if proposal could cover.

    0 讨论(0)
提交回复
热议问题