Шаблонная специализация конкретных участников?

Надо надеяться, Вы понимаете изображения. Мудрый производительностью, они эквивалентны - никакое различие.

РЕДАКТИРОВАНИЕ: ой. Угадайте, что Вы не заботились о той части ответа.

24
задан Johannes Schaub - litb 5 October 2011 в 04:51
поделиться

2 ответа

Вы можете только специфицировать его явно, указав все аргументы шаблона. Частичная специализация для функций-членов шаблонов классов не допускается.

template <typename T,bool B>
struct X
{
    void Specialized();
};

// works
template <>
void X<int,true>::Specialized()
{
    ...
}

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

// "maps" a bool value to a struct type
template<bool B> struct i2t { };

template <typename T,bool B>
struct X
{
    void Specialized() { SpecializedImpl(i2t<B>()); }

private:
    void SpecializedImpl(i2t<true>) { 
      // ...
    }

    void SpecializedImpl(i2t<false>) { 
      // ...
    }
};

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

template<typename T, bool B>
struct SpecializedImpl;

template<typename T>
struct SpecializedImpl<T, true> {
  static void call() { 
    // ...
  }
};

template<typename T>
struct SpecializedImpl<T, false> {
  static void call() { 
    // ...
  }
};

template <typename T,bool B>
struct X
{
    void Specialized() { SpecializedImpl<T, B>::call(); }
};

. Я считаю, что обычно требуется больше кода, и я считаю, что перегрузку функции легче обрабатывать, в то время как другие предпочитают отложить до шаблона класса. В конце концов, это дело вкуса. В этом случае вы могли бы поместить этот другой шаблон внутрь X также как вложенный шаблон - в других случаях, когда вы специализируетесь явно, а не только частично, вы не можете этого сделать, потому что вы можете явно указать специализации только в области пространства имен, а не в области класса.

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

template <typename T,bool B>
struct X
{
private:
    // maps a type and non-type parameter to a struct type
    template<typename T, bool B>
    struct SpecializedImpl { };

public:
    void Specialized() { Specialized(SpecializedImpl<T, B>()); }

private:
    template<typename U>
    void Specialized(SpecializedImpl<U, true>) {
      // ...
    }

    template<typename U>
    void Specialized(SpecializedImpl<U, false>) {
      // ...
    }
};

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

29
ответ дан 28 November 2019 в 23:59
поделиться

Это то, что я придумал, неплохо :)

//The generic template is by default 'flag == false'
template <class Type, bool flag>
struct something
{
    void doSomething()
    {
        std::cout << "something. flag == false";
    }
};

template <class Type>
struct something<Type, true> : public something<Type, false>
{
    void doSomething() // override original dosomething!
    {
        std::cout << "something. flag == true";
    }
};

int main()
{
    something<int, false> falseSomething;
    something<int, true> trueSomething;

    falseSomething.doSomething();
    trueSomething.doSomething();
}
3
ответ дан 28 November 2019 в 23:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: