Вопрос о шаблонной функции C ++ - PullRequest
4 голосов
/ 02 января 2011

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

template< typename fromType, typename toType> struct DataTranslator;

Я могу заставить его работать со следующими объявлениями функции шаблона перевода:

template< typename Return, typename Direction, typename ValType, typename TransType>
Return translate(ValType val, TransType& trans);

template< typename Return, typename Direction, typename ValType, typename TransType, typename... OtherTrans>
Return translate(ValType val, TransType& trans, OtherTrans&... others);

Затем я могу сделать что-то вроде следующего:1007 *

DataTranslator<specificBaud, universalBaud>::type baudTranslator;
DataTranslator<universalBaud, std::string>::type baudCmdTranslator;

specificBaud myBaud;
....
std::string result = translate<std::string, forward_trans>(myBaud, baudTranslator, baudCmdTranslator);

но если я изменю объявление моих функций перевода на:

template< typename Return, typename Direction, typename ValType, typename FT, typename TT>
Return translate(ValType val, typename DataTranslator<FT, TT>::type& trans);

template< typename Return, typename Direction, typename ValType, typename FT, typename TT, typename... OtherTrans>
Return translate(ValType val, typename DataTranslator<FT, TT>::type& trans, OtherTrans&... others);

, я получаю ошибку вызова не соответствующей функции при выполнении вызова перевода.Я использую GCC 4.5 для моего компилятора с флагом -std = c ++ 0x.

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

1 Ответ

4 голосов
/ 02 января 2011

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

template <typename T> void DoSomething(typename std::vector<T>::iterator itr);

std::vector<int> v;
DoSomething(v.begin());

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

template <typename T> class Pathological {
      typedef int type;
};

template <typename T> void WhatIsT(typename Pathological<T>::type huh);

Проблема здесь в том, что каждый экземпляр Pathological имеет один и тот же тип, указанный для его типа. Следовательно, если вы передадите Pathological<int>::type или Pathological<double>::type, компилятор не сможет определить, каким был внешний тип, потому что оба этих типа имеют значение int.

Надеюсь, это поможет!

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