Шаблоны классов с повторяющимися именами? - PullRequest
9 голосов
/ 27 февраля 2012

Можно ли определить два разных шаблона (по количеству аргументов шаблона) с одним и тем же именем?

Вот что я пытаюсь сделать:

namespace MyNamespace
{

template<class TRet>
class FunctionObject
{
    typedef typename TRet ReturnType;
    virtual ReturnType const operator()() const = 0;
};


template<class TRet, class TArg0>
class FunctionObject
{
    typedef typename TRet ReturnType;
    typedef typename TArg0 FirstArgumentType;
    virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};

}

Я получаюошибка при упоминании слишком большого числа аргументов шаблона в конце закрывающей скобки второго * FunctionObject определения структуры.

Я знаю, что это можно сделать в C #, но не был уверен в C ++.Может кто-нибудь, пожалуйста, пролить немного света здесь?

Ответы [ 4 ]

11 голосов
/ 27 февраля 2012

Я думаю, что частичная специализация поможет:

namespace MyNamespace {

  template<class TRet, class TArg0>
  class FunctionObject
  {
      typedef typename TRet ReturnType;
      typedef typename TArg0 FirstArgumentType;
      virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
  };

  template<class TRet>
  class FunctionObject<TRet,void>
  {
      typedef typename TRet ReturnType;
      virtual ReturnType const operator()() const = 0;
  };

}

Вы также можете начать с основного шаблона с более чем одним параметром.

Я думаю, что C ++ 11 с его вариативными шаблонами позволяет сделать это более изящным, но у меня не было времени поиграть с этим, поэтому я бы лучше оставил это кому-то еще, чтобы показать.

6 голосов
/ 27 февраля 2012

Чтобы показать предлагаемое sbi решение для вариабельных шаблонов:

namespace MyNamespace {

  template<typename...> FunctionObject;

  template<class TRet, class TArg0>
  class FunctionObject<TRet,TArg0>
  {
      typedef typename TRet ReturnType;
      typedef typename TArg0 FirstArgumentType;
      virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
  };

  template<class TRet>
  class FunctionObject<TRet>
  {
      typedef typename TRet ReturnType;
      virtual ReturnType const operator()() const = 0;
  };

}

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

5 голосов
/ 27 февраля 2012

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

struct null_type {};

template<class TRet, class TArg0 = null_type>
class FunctionObject
{
    typedef typename TRet ReturnType;
    typedef typename TArg0 FirstArgumentType;

    //both functions here
    virtual ReturnType const operator()() const = 0;

    virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};
1 голос
/ 27 февраля 2012

Я считаю, что что-то вроде этого также будет работать, но наличие отдельных классов может не быть тем, что вы ищете:

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