Порядок аргументов шаблона для функции - PullRequest
2 голосов
/ 09 апреля 2011

В приведенном ниже коде среди 2 аргументов шаблона я использую один из них неявно, а другой явно:

class A {};

template<typename ToType, typename FromType>
ToType CompileTimeCast (FromType pointer)
{
  return (ToType)(pointer);
}

int main ()
{
  A *pA;
  int *pi = CompileTimeCast<int*>(pA); // function invocation
}

Работает нормально. Теперь, если я поменяю местами ToType и FromType в списке аргументов, компилятор выдаст ошибку как:

 error: no matching function for call to ‘CompileTimeCast(A*&)’

Было бы любопытно узнать, почему компилятор жалуется, когда он знает, что оба аргумента различаются при вызове функции и один аргумент уже используется?

Ответы [ 3 ]

3 голосов
/ 09 апреля 2011

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

int *pi = CompileTimeCast<int*, const int*>(pA);

В этом примере, исходя из вашего исходного кода, ToType равно int*, а FromType равно const int*. Если вы явно укажете только подмножество аргументов шаблона, компилятор будет вынужден предположить, что ваше подмножество - это первые несколько аргументов шаблона по порядку. И все аргументов конечного шаблона должны быть выводимыми.

Обратите внимание, что для набора аргументов шаблона, который выводит компилятор, порядок не имеет значения. В вашем примере выводится only FromType.

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

2 голосов
/ 09 апреля 2011

Сменив, если вы имели в виду это:

template<typename FromType, typename ToType> //argument swapped their position!
ToType CompileTimeCast (FromType pointer)

Тогда вывод аргумента больше не будет работать.Потому что, когда вы пишете CompileTimeCast<int*>, компилятор предполагает, что int* всегда является первым аргументом в списке аргументов шаблона функции.И второй аргумент будет выведен компилятором.

Теперь вы должны явно указать типы как:

int *pi = CompileTimeCast<A*, int*>(pA); //FromType=A*, ToType=int*
0 голосов
/ 09 апреля 2011

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

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