Как позволить пользователям MyClass контролировать, какая версия класса создается с помощью флага компилятора? - PullRequest
0 голосов
/ 26 мая 2018

У меня есть класс C ++, который выполняется в чувствительном ко времени коде, поэтому простое создание объекта может занять больше времени, чем пользователи могут потратить.Я хотел бы определить как стандартную, так и тривиально конструируемую версию моего класса, и позволить пользователям класса контролировать, какая версия класса создается с помощью флага компилятора.Я бы хотел, чтобы флаг компилятора работал на уровне group.Например, если бы флаг был LEVEL=:OFF,GROUP1:ON, то тривиальная версия была бы построена для всех экземпляров класса, кроме тех, что в GROUP1, что позволило бы получить фактическую, нетривиальную реализацию.Цель состоит в том, чтобы пользователи могли отключать определенные группы во время компиляции, изменяя значение флага.

Я бы хотел использовать std::conditional в C ++ 11 для управления тем, какая версия класса используется.Для этого мне нужно проверить группу, с которой связано данное использование класса, и сравнить ее с настройкой флага компилятора для этой группы.Я не могу придумать, как пользователи этого класса передают настройку времени компиляции в определение основного класса из исходного файла пользователя.Я мог бы потребовать, чтобы пользователи добавили что-то вроде #define MYCLASS_GROUP ON в свой исходный файл, но я не думаю, что смогу сослаться на это в файле, где определен мой класс.

Есть ли способ для пользователей класса управлять скомпилированной версией класса из исходного файла пользователя?Заранее спасибо за любые идеи здесь!

Обновление: вот как я бы идеально хотел, чтобы это использовалось.Пользователь может сделать:

#define MYCLASS_GROUP GROUP1

MyClass myClassInstance;

Затем он может контролировать, какая версия создается с помощью флага компилятора.Так что -DMYCLASS_GROUP_LEVEL=:OFF,GROUP1:ON включит варианты использования, подобные описанным выше, в GROUP1.

В определении класса я хотел бы что-то вроде следующего нерабочего псевдокода:

class MyClassOn {
  non-trivial code here
};
class MyClassOff {
};
typedef std::conditional<check-group-here, MyClassOn, MyClassOff>::type MyClass;

Ответы [ 2 ]

0 голосов
/ 26 мая 2018
#define MYCLASS_GROUP GROUP1
MyClass myClassInstance;

не работает.Обычно, если вам нужно настроить код lib препроцессором, вы определяете идентификатор перед включением заголовка lib.

#define MYCLASS_GROUP GROUP1
#include <MyClass.h>

MyClass myClassInstance;

В MyClass.h вы просто проверяете, что определено.

В вашем конкретном случае вы не делаетене нужен препроцессор, как хорошо описано в ответе Роберта Анджеюка.

0 голосов
/ 26 мая 2018

Вы можете использовать специализацию шаблона.

Сначала объявите параметры:

class DefaultVersion;
class TriviallyConstructible;

Затем создайте определение основного шаблона класса

template <typename T = DefaultVersion>
class MyClass;

Специализация для DefaultVersion:

template< >
class MyClass< DefaultVersion >
{
    // ...
};

Специализация для тривиально-конструируемой версии

template<>
class MyClass< TriviallyConstructible >
{
    // ...
};

Пример использования

MyClass<> m1;
MyClass< DefaultVersion > m2; // same as m1
MyClass< TriviallyConstructible > m3;

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


Как передать флаг времени компиляции в класс?

С помощью директив препроцессора и псевдонимов.

#ifdef GROUP1 > 0
using MyClassGroup1 = MyClass< TriviallyConstructible >;
#else
using MyClassGroup1 = MyClass< DefaultVersion >;
#endif

Или другим способом:

#ifdef GROUP1 > 0
using Group1 = TriviallyConstructible;
#else
using Group1 = DefaultVersion;
#endif

и в месте использования

MyClass< Group1 > m4;
...