Is it possible to conditionally declare a friend class in C ++ 03?

I want to declare a friend class only if some condition (compilation time) is true. For instance:

// pseudo-C++ class Foo { if(some_compile_time_condition) { friend class Bar; } }; 

I did not find a solution on the Internet. I went through all the answers to the question Dynamic creation of structures at compile time . Many of them use C ++ 11 std::conditional , but I would like to know if this can be done in C ++ 03 without using a preprocessor.

This solution is https://stackoverflow.com/a/16626966/2126326 because the friend ship is not inherited ( friend class with inheritance ).

Change To make this more easily visible, as noted in the comment below: This requirement is unusual. This is part of a new hardware modeling research project I am working on. Testbench is written in C ++, and I want to display variables in wave form. I explored various other options and realized that I needed to use a friend class due to practical reasons. A friend will capture the values ​​and form a waveform, but I would rather have a friend only when a waveform is required, and not all the time.

+4
source share
5 answers

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

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

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

Note that the class name of the dummy class must match the name of the potential friend in this workaround.

+6
source

[class.friend] / 3 says the following:

A friend declaration that does not declare a function must take one of the following forms:
friend specified type specifier

friendly simple type specifier

friend typename-specifier;

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

+2
source

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

However, I would like to note that:

  • Friendship does not require you to actually use.
  • Friendship is a pure compilation time construct (e.g. access specifiers) and carries no penalty for execution in all major compilers

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

Note: in the future, this static_if clause may cover.

+2
source

Note: Johannes pretty much nailed it. In '03 you cannot be friends with typedef - but if you know that you have a class, then you can refer to this injected class name .

Johannes's answer also has the advantage of using standard library functions, which is also always good.

 #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 still differs from the requirement that Foo always has a friend, but make friends with class changes based on the value of the option.

An interesting question is the question of whether this is a violation of the ODR version of Foo with or without some_compile_time_condition set to 1.

0
source

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

 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 the preprocessor, and if you add this preprocessor, then at compile time your Bar class will be a friend class ... you can use this preprocessor wherever you want the Bar class to be like a friend class. compile without a preprocessor, then it will not allow you to add Bar as a Foo friends class

Please correct me if I misunderstood the question.

0
source

All Articles