Где / как определить шаблон - PullRequest
3 голосов
/ 09 февраля 2010

Какова наилучшая практика в отношении определения шаблона в C ++?

template <class T>
class A
{
private:
    // stuff
public:
    T DoMagic()
    {
        //method body
    }
}

Or:

template <class T>
class A
{
private:
    // stuff
public:
    T DoMagic();
}

template <class T>
A::T DoMagic()
{
    // magic
}

Другой способ? Я, кажется, спотыкаюсь о некотором противоречии относительно этой темы. Так; Какой путь выбрать?

Ответы [ 6 ]

4 голосов
/ 09 февраля 2010

Это полностью вопрос стиля. Тем не менее, сказал:

  1. выберите способ и придерживайтесь его - либо все встроенное, либо полное, либо смешанное на основе некоторого правила
  2. лично я использую правило 3 строк. Если тело метода в шаблоне длиннее 3 строк, я перемещаю его наружу.

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

2 голосов
/ 09 февраля 2010

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

При написании простого шаблона, используемого только в одном месте, объявляйте и определяйте его в соответствии с объявлениями прямо в файле CPP, где вы собираетесь его использовать. Нет смысла форсировать глобальную перекомпиляцию, если этот шаблон нужен только одному блоку кода.

file.cpp

template<class Gizmo> bool DoSomethingFancy()
{
 // ...
}

Для небольших шаблонных утилит, используемых в единицах перевода, определите и объявите их вместе в файле H:

utility.h

template<class Gizmo> bool DoSomethingUseful() 
{
  // ...
}

По мере усложнения ваших шаблонов становится все более важным иметь возможность просматривать объявление отдельно от определения. Сначала держите все отдельно, но в одном файле:

utility.h

template<class Type> class Useful
{
  bool FunctionA();
  bool FunctionB();
};

template<class Type> bool Useful<Type>::FunctionA()
{
  // ...
}

template<class Type> bool Useful<Type>::FunctionB()
{
  // ...
}

Но в конце концов даже это станет громоздким. Когда это произойдет, разделите его на файл заголовка для объявлений и файл INC для определений. В конце заголовочного файла #include файл INC:

utility.h:

template<class Type> class MoreUseful
    {
      bool FunctionA();
      bool FunctionB();
    };

#include "utility.inc"

utility.inc:

template<class Type> bool MoreUseful<Type>::FunctionA()
{
  // ...
}

template<class Type> bool MoreUseful<Type>::FunctionB()
{
  // ...
}
1 голос
/ 09 февраля 2010

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

1 голос
/ 09 февраля 2010

Я обычно определяю все методы снаружи, но каждый раз, когда я хочу, чтобы в C ++ были какие-то "блоки шаблона":

template <class T>
struct A
{
     T foo();
     T bar(T * t);
     T baz(T const & t);
};

template <class T>  // Made-up syntax
{
    T A::foo()
    {
        //...
    }

    T A::bar(T * t)
    {
        //...        
    }

    T A::baz(T const & t)
    {
        //...
    }
}
1 голос
/ 09 февраля 2010

Это религиозный (стиль) вопрос. Я предпочитаю определять свои функции вне объявления шаблона для классов, которые имеют более одного метода или несколько простых методов.

В любом случае, я понимаю, что объявление шаблона и определения метода должны находиться в одной и той же единице перевода. Это потому, что template больше похож на трафарет , компилятор подключает данный тип к трафарету и генерирует код для данного типа.

Что бы вы ни решили, просто будьте последовательны.

0 голосов
/ 09 февраля 2010

Для одноразового экземпляра, подобного вашему примеру, это мало что меняет.

Что происходит, когда есть много шаблонов с большим количеством вариаций? Затем это помогает собрать вместе схожие яблоки и схожие апельсины вдали от них. Конечно, все это должно быть сделано так же интуитивно, как и практично. На это сильно влияет культура программистов, работающих с кодом.

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