2016-06-25 3 views
6

Я перегрузил функцию в своем классе строк, однако ее никогда не вызывают. Зачем?Templated function not called

template <class T> 
class StringT { 
public: 
    void assign(const T* ptr); 
    template <size_t N> void assign(const T(&ptr)[N]); 
}; 

int main() { 
    StringT<char> str; 
    str.assign("Hello World"); //calls "void assign(const T* ptr)" although type is (const char[12]) 
} 
+1

Интересно, я бы этого не ожидал. Я сделал несколько более сложный пример здесь: http://cpp.sh/7hnfk, который согласен с утверждением Microsoft, что auto s = «вещь»; приведет по умолчанию к const char * (https://msdn.microsoft.com/en-us/library/69ze775t.aspx). – Arunas

ответ

6

Для получения дополнительной справки, некоторые конкретные ссылки на Стандарт:

13.3.3 Лучшей жизнеспособная функция

С учетом этих определений жизнеспособная функция F1 определена как лучшая функция, чем другая жизнеспособная функция F2, если для всех аргументов i ICSi (F1) не является худшей последовательностью преобразования, чем ICSi (F2), а затем. ..

  • F1 не шаблон функции специализации и F2 шаблон функции специализации ...

В этом случае функция, не шаблонный (очевидно) не шаблон функции специализация и преобразование "Hello World" в char const* не хуже, чем const char[N], согласно правилам ранжирования, определенным в таблице в разделе «Стандартные последовательности преобразования». Согласно этой таблице, как No conversions required, так и Array-to-pointer conversion считаются точными совпадениями в контексте разрешения перегрузки. Аналогично, если шаблонные перегрузки заменяются на не-шаблонную перегрузку (то есть, как void assign(const T(&ptr)[12]);), то компиляция str.assign("Hello World"); завершится неудачей из-за неоднозначного вызова.

Чтобы убедиться, что функция не-шаблон не рассматриваются для перегрузки, есть следующее примечание в разделе «Явная спецификации аргумента шаблона»:

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

Для этого вы можете использовать str.assign<>("Hello World");.

+0

Благодарим вас за это разъяснение. Не могли бы вы также опубликовать ссылку на этот стандарт? – mvidelgauz

+0

Стандартные выпуски не доступны свободно из того, что я могу сказать, но вы можете получить черновики в http://www.open-std.org/jtc1/sc22/wg21/ в соответствии с [последним общедоступным проектом] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf). Не уверен, есть ли лучший способ, хотя ... – mkal

+2

Я все еще пытаюсь примирить это с тем, что: StringT str; char hw_array [] = "Hello World"; str.assign (hw_array); вызывает шаблон версии – Arunas

3

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

Детали here

Если вы хотите сохранить функцию, не шаблонный, но принудительно назвать шаблон один попробовать

str.template assign("Hello World"); 
+0

может зависеть от компилятора, но если версия const T * закомментирована, вместо нее вызывается другая. Я не вижу никаких интересных ошибок. – Arunas

+0

@Arunas Я отредактировал свой ответ, поэтому наши комментарии теперь неактуальны. Я удалил мой – mvidelgauz

+0

Есть ли способ заставить компилятор вызвать функцию шаблона? – Philinator