У меня есть этот класс:
template <typename T, uint64_t N>
struct Probe {
static const uint64_t Counter = N;
typedef T Type;
};
Который я использую как:
typedef Probe <int, 0> FirstIntProbe;
typedef Probe <int, 1> SecondIntProbe;
typedef Probe <float, 2> FloatProbe;
Можно ли создать метод времени компиляции \ макроса, который позволяет мне создавать экземпляры этого класса без указания второго параметра, такого как:
typedef Probe <int, Something?> FirstIntProbe;
typedef Probe <int, Something?> SecondIntProbe;
typedef Probe <float, Something?> FloatProbe;
Я предполагаю, что это невозможно, но опять же я видел, как люди делают вещи на C ++, я не думал, что это было возможно раньше.
Обновить:
Вы можете посмотреть на использование __COUNTER__
макрос, который является расширением компилятора (но поддерживается на НКУ а также MSVC, среди прочих). Обратите внимание, что __COUNTER__
является уникальным только для каждой единицы перевода, т.е. .cpp
файл.
редактировать: Включение заголовка в несколько блоков перевода в порядке. Этот пример связывает и работает отлично (построен на GCC 4.5):
probe.h:
template <typename T, int N>
struct Probe {
typedef T Type;
};
#define DECLARE_PROBE(type) typedef struct Probe<type, __COUNTER__>
main.cpp:
#include "test.h"
DECLARE_PROBE(int) intprobe;
DECLARE_PROBE(float) floatprobe;
int main(int argc, char** argv) {
intprobe ip;
floatprobe fp;
return 0;
}
test.cpp:
#include "test.h"
DECLARE_PROBE(int) intprobe;
DECLARE_PROBE(float) floatprobe;
static intprobe ip;
static floatprobe fp;
Это на самом деле очень просто если вам не нужен интеграл
константное выражение (т.е. вы не используете Counter
как
размерность массива или тому подобное): просто используйте глобальную статическую для
счетчик (или поместить его в базовый класс без шаблонов), и
увеличивайте его каждый раз, когда вы используете его при инициализации.
Что-то вроде:
int currentProbeCounter;
template <typename T>
struct Probe
{
static int const counter;
// ...
};
template <typename T>
const int Probe<T>::counter = ++ currentProbeCounter;
Обратите внимание, что это будет только распределять Probe<T>::counter
за
данный тип, когда (или если) вы используете его; вы можете использовать его
в конструкторах Probe
(даже если вам не нужно)
обеспечить его создание. (С другой стороны, если вы никогда не используете его,
кого это волнует, если он никогда не был создан.)
Вы могли бы использовать Boost.Preprocessor сделать эту работу для вас.