Мне нужен способ иметь одну статическую переменную для всех типов типов моего шаблона
template <class T> class Foo { static Bar foobar;};
Хорошо, строка выше будет генерировать объект Bar с именем foobar для каждого типа T
, но это не то, что я хочу, я в основном хочу способ объявления переменной типа Bar, поэтому каждый объект типа Foo
имеет доступ к той же переменной foobar
, независимо от T
.
Я пытался использовать другой класс для хранения личных вещей, но это не работает, потому что стандарт не разрешает такие вещи, как template <class T> friend class Foo<T>;
Таким образом, очевидное решение (показанное ниже) состоит в том, чтобы иметь глобальную переменную Bar foobar
, но это явно нарушает концепцию сокрытия информации (правильной инкапсуляции):
Bar Foo_DO_NOT_TOUCH_THIS_PLEASE_foobar;
template <class T> class Foo { static Bar& foobar;};
template <class T> Bar& Foo<T>::foobar=Foo_DO_NOT_TOUCH_THIS_PLEASE_foobar;
Конечно, вы можете дополнительно использовать детализированное пространство имен (это то, чем я сейчас занимаюсь), но есть ли другой способ, который действительно запрещает пользователям возиться с вашими личными статическими переменными?
Кроме того, это решение будет довольно запутанным, когда вам придется объявлять множество статических методов аналогичным образом, поскольку вам, скорее всего, придется экстенсивно использовать ключевое слово friend, например friend RetType Foo_detail::StaticFunc(ArgT1, ArgT2)
.
И у пользователей не будет приятного интерфейса, поскольку они не могут использовать эти функции, как они используются для Foo<T>::someFunc()
, но вместо этого им придется вызывать что-то вроде Foo_static::someFunc()
(если вы используете пространство имен Foo_static
для открытых статических функций ).
Так есть ли какое-либо другое решение, которое не нарушает инкапсуляцию и / или не вводит много синтаксических издержек?
EDIT:
основываясь на всех ваших ответчиках, я попробовал следующее, и оно работает как задумано:
typedef int Bar;
template <class T> class Foo;
class FooBase
{
static Bar foobar;
public:
template <class T> friend class Foo;
};
Bar FooBase::foobar;
template <class T> class Foo : public FooBase
{
public:
using FooBase::foobar;
};
Преимущество этого решения в том, что пользователи не могут наследовать от FooBase.