Может ли класс друзей быть объявлен условно в C ++ 03?

Я хочу объявить класс друга только в том случае, если какое-либо условие (во время компиляции) выполняется. Например:

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

Я не нашел никакого решения в интернете. Я прошел все ответы на вопрос Динамическое создание структур во время компиляции. Многие из них используют C ++ 11 std::conditional, но я хотел бы знать, если это возможно сделать в C ++ 03 без использования препроцессора.

Это решение https://stackoverflow.com/a/11376710/252576 не будет работать, потому что friendКорабль не передается по наследству ( класс друга с наследованием ).

редактировать Просто чтобы сделать это более заметным, как указано ниже в комментарии: Это требование необычно. Это часть нового исследовательского проекта по аппаратному моделированию, над которым я работаю. Testbench написан на C ++, и я хочу отобразить переменные в форме сигнала. Я исследовал различные другие варианты, и понял, что мне нужно использовать friend classИз-за практических соображений. Друг захватит значения и сгенерирует сигнал, но я бы предпочел иметь друга только тогда, когда требуется сигнал, а не все время.

4

Решение

использование friend std::conditional<C, friendclass, void>::type; где C это ваше состояние. Друг, не относящийся к классу, будет игнорироваться.

Условный шаблон легко реализуется в C ++ 03. Однако, поскольку C ++ 03 не поддерживает друзей typedef, вам необходимо использовать следующий синтаксис

namespace detail { class friendclass {}; }

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

Обратите внимание, что в этом обходном пути подробное имя класса-пустышки должно совпадать с именем потенциального друга.

6

Другие решения

[class.friend] / 3 говорит это:

Объявление друга, которое не объявляет функцию, имеет одну из следующих форм:
друг разработал спецификатор типа;
простой указатель типа друга;
спецификатор typename друга;

поэтому невозможно объявить друзей класса без макроса.

2

Это кажется, к сожалению, это невозможно в компиляторе C ++: то есть кажется, что здесь может помочь только препроцессор. Примечание: у Йоханнеса есть предложение, поэтому есть надежда!

Однако я бы отметил, что:

  • дружба не требует, чтобы вы действительно использовали это
  • дружба является чистой конструкцией времени компиляции (например, спецификаторами доступа) и не влечет за собой никаких штрафных санкций во время выполнения на любом крупном компиляторе

нет причин не иметь безусловный дружба, но используйте ее, только если выполнены некоторые условия (статические или динамические).

Примечание: в будущем это то, что static_if предложение может охватывать.

2

Замечания: Johannes в значительной степени прибил это. В ’03 ты не сможешь подружиться
typedef — но если вы знаете, что у вас есть класс, то вы можете обратиться к
его injected class name,

Ответ Йоханнеса также имеет преимущество использования стандартной функциональности библиотеки, что тоже всегда хорошо.

#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;
}

Это все еще отличается от требования в том, что Foo всегда имеет
друг, но класс подружился меняется в зависимости от значения
вариант.

Интересный побочный вопрос заключается в том, является ли нарушение ODR иметь
версии Foo как с, так и без some_compile_time_condition
установить на 1.

0

Я думаю, что вы берете 1 препроцессор и пишете свой исходный код внутри него.

bool flag = false;
#ifdef _MY_FRIEND_
friend class sample
flag = true;
#endif

if (flag)
{
...
...
...
}

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

};

Здесь _MY_FRIEND_ — препроцессор, и если вы добавите этот препроцессор, то во время компиляции ваш класс Bar станет классом друга … вы можете использовать этот препроцессор в любом месте, когда вам понадобится класс Bar в качестве друга, класса. препроцессор, то он не позволит вам добавить Bar в качестве друга класса Foo

Пожалуйста, поправьте меня, если я неправильно понял вопрос.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector