Другой подход к одной статической переменной для шаблонного класса - PullRequest
0 голосов
/ 11 февраля 2010

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

Несмотря на ответ, это вдохновило меня попробовать другой подход. Вместо использования наследования я придумал следующее:

class Bar {};

class {
private:
    Bar bar;
    template <class T> friend class Foo;
} static foobar_singleton;

template <class T> 
class Foo 
{ 
public:
    static Bar bar() { return foobar_singleton.bar; }
};

Для меня foobar_singleton работает аналогично «статическому приватному элементу, не являющемуся членом», поскольку его содержимое будет доступно только шаблонному классу Foo. Это также позволяет избежать наследования, хотя я не уверен, что это на самом деле преимущество. Мое решение кажется возможным содержать только заголовки, без необходимости в другом файле определения.

Я хотел бы посмотреть, каково мнение об этом подходе по сравнению с тем, которое использовалось в качестве ответа для темы, которая меня заинтересовала. Например, некоторые примеры вопросов, о которых я хотел бы услышать:

1. Видите ли вы какое-либо явное преимущество в моем примере? Или, если на то пошло, явная дезавуация?
2. Вы бы посоветовали сделать атрибут bar статическим членом и назвать класс, используемый как singleton?
3. Это напоминает кому-нибудь из вас какой-нибудь шаблон дизайна? Похоже на pimpl идиома, может быть?
4. Вы видите какие-либо проблемы с переносимостью компилятора? (Я проверял это только с MSVC и GCC)
5. Я прав, что я являюсь возможной реализацией только для заголовков? Я на самом деле не совсем уверен насчет статической переменной foobar_singleton

Заранее спасибо!

1 Ответ

2 голосов
/ 22 сентября 2010

Статическая переменная foobar_singleton в вашем примере будет отличаться от каждой единицы перевода (внутренняя связь!). Что-то вроде шоу-стоппера.

Наследование в исходной теме используется только для «вставки» общей статической переменной в пространство имен шаблона. Если это не является обязательным требованием, просто не извлекайте Foo из FooBase, он работает точно так же.
Если бы это было необходимо по какой-либо причине, я бы получил информацию в частном порядке, что должно устранить любые возможные побочные эффекты, которые могут возникнуть при введении дополнительного базового класса. И, конечно, добавьте вспомогательный класс в качестве последнего базового класса, если Foo наследует и другие классы.

Если вы хотите решение только с заголовком:

typedef int Bar;


template <class DummyType>
class FooCommonStatics
{
    static Bar s_bar;

    template <class T>
    friend class Foo;
};

template <class DummyType>
Bar FooCommonStatics<DummyType>::s_bar;

template <class T>
class Foo
{
public:
    // void is just a dummy-type, any type that's not dependent on T would do
    typedef FooCommonStatics<void> CommonStatics;

    Foo()
    {
        CommonStatics::s_bar++;
    }

private:
    T m_something;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...