2012-03-09 3 views
1

У меня есть функция, которая принимает три аргументашаблона или функция перегрузки для общего аргумента

void replace(const string, const string, string*) ; 

Моей проблемой является вторым аргументом, который я хотел бы переписать так что он может быть либо строкой, либо объект Path (из библиотеки Boost Filesystem, но на самом деле любой объект, который может рассматриваться как строка, должен делать), поэтому мне не нужно преобразовывать пути в строки по всему месту.

Я знаю, что могу перегрузить функцию и сделать две реализации, это то, что я делаю сейчас, так у меня есть две реализации одного и того же функции:

void replace(const string, const string, string*) ; 
void replace(const string, const path, string*) ; 

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

template <class T> 
void replace(const string, const T, string*) ; 

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

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

Каков наилучший способ справиться со всем этим? Нет ли лучшего способа, чем иметь более одной реализации одной и той же функции?

+0

Перегрузки, вероятно, правильный подход. Также вы, вероятно, должны принять эти аргументы по ссылке const. Кроме того, указатели являются уродливыми и неконстантными ссылками лучше. –

+0

@CatPlusPlus Что вы подразумеваете под ссылкой не-const здесь? Я думал, что это то, что я делал (предполагая, что вы говорите о третьем аргументе) –

+0

Третий аргумент - это указатель. Ссылки сделаны с амперсандом: 'void replace (const std :: string &, const std :: string &, std :: string &);' –

ответ

6

Перегруженные функции - лучший подход для вашего использования.

Я обычно хожу по следующим правилам:

  • Если вы хотите выполнить те же действия на различных типов данных затем предпочитающих шаблоны.

  • Если вы хотите выполнить различных действий на различных типов данных то предпочитают перегрузку функции.

Ваш случай использования относится ко второй категории.

+0

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

1

Почему бы не просто сделать функцию, как:

void replace(const string s, const path p, string* ss) { 
    replace(s, convert_to_string(path), ss); 
} 

Пусть оптимизатор решить, как он должен справиться с этим. Что не элегантно? Ваш метод шаблонов будет делать то же самое, это будет просто сложнее.

+0

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

Смежные вопросы