Есть у меня код, позволяющий запросить параметр с класса по такому синтаксису:
// описание контейнера параметровstruct OneOfParamCont
{
int param1;
float param2;
};
// объект, может реализовать любой из классов параметровstruct Object
{
// запрос параметра у объекта
// если объект хранит в себе OneOfParamCont, то ф-ция вернёт значение параметра
// иначе вернёт defaultVal template<typename ParamClass, typename ParamType>
ParamType QueryParam( ParamType (ParamClass::*param), const ParamType& defaultVal = ParamType() )
{ ... }
};
Запросы вот такие:
int val = object.QueryParam( &OneOfParamCont::param1 );
float val2 = object.QueryParam( &OneOfParamCont::param2, 1.f );
Всё работает замечательно, но захотелось мне добавить перегрузку, чтобы возвращаемое значение можно было задавать самому, по такому синтаксису:
жалуется на ambiguity, потому что обе ф-ции подходят под определение, для второй декларации ResultType выводится из дефолтного значения
В общем как ни игрался, не вышел каменный цветок. Хочется сохранить именно такой интерфейс использования, чтобы у обоих вариантов было возвращаемое дефолтное значение.
Ты хотя бы полный пример показал. У меня и на gcc и на vs компилится: http://ideone.com/bZaHQl
J> template<typename ParamClass, typename ParamType> J> ParamType QueryParam( ParamType (ParamClass::*param), const ParamType& defaultVal = ParamType() ) J> { ... }
как вариант попробуй поменять местами параметры шаблона у этой функции.
P.S. А что у тебя внутри делает функция с ResultType? static_cast?
Здравствуйте, Piko, Вы писали:
P>Ты хотя бы полный пример показал. У меня и на gcc и на vs компилится: http://ideone.com/bZaHQl
J>> template<typename ParamClass, typename ParamType> J>> ParamType QueryParam( ParamType (ParamClass::*param), const ParamType& defaultVal = ParamType() ) J>> { ... }
P>как вариант попробуй поменять местами параметры шаблона у этой функции.
Не совсем понял. Вот так?
template<typename ParamType, typename ParamClass>
ParamType QueryParam( ParamType (ParamClass::*param), const ParamType& defaultVal = ParamType() )
template<typename ResultType, typename ParamType, typename ParamClass>
ResultType QueryParam( ParamType (ParamClass::*param), const ResultType& defaultVal = ResultType() )
// остаётся abmiguity по тем же самым причинамfloat val2 = object.QueryParam( &OneOfParamCont::param2, 1.f );
P>P.S. А что у тебя внутри делает функция с ResultType? static_cast?
Вызывает конвертер. Впрочем это детали мимо дела — реальный код несколько сложнее, не хочу вдаваться в подробности без насущной необходимости.
Здравствуйте, johny5, Вы писали:
P>>Ты хотя бы полный пример показал. У меня и на gcc и на vs компилится: http://ideone.com/bZaHQl
Так у тебя мой пример скомпилировался?
P>>как вариант попробуй поменять местами параметры шаблона у этой функции. J>Не совсем понял. Вот так?
да
P>>P.S. А что у тебя внутри делает функция с ResultType? static_cast? J>Вызывает конвертер. Впрочем это детали мимо дела — реальный код несколько сложнее, не хочу вдаваться в подробности без насущной необходимости.
ну ок, просто если static_cast — то вся эта конструкция лишняя..
Здравствуйте, Piko, Вы писали:
P>Здравствуйте, johny5, Вы писали:
P>>>Ты хотя бы полный пример показал. У меня и на gcc и на vs компилится: http://ideone.com/bZaHQl
P>Так у тебя мой пример скомпилировался?
P>>>как вариант попробуй поменять местами параметры шаблона у этой функции. J>>Не совсем понял. Вот так?
P>да
Подожди, оно собирается и твоё и даже моё оригинальное...
В общем я разобрался — как обычно бывает, упрощая, я упростил выкинув проблемное место, и т.е. проблему я искал не там. В оригинале QueryParam были размножены (в отсутствии вариадиков) до N параметров, так что в одном QueryParam можно спрашивать параметр от разных классов (лишь бы результирующие типы совпадали).
И неоднозначность возникала именно из-за них, ибо на место typename Param2 подставлялись явно заданные дефолтные аргументы и всё ломалось.
Переписав менее абстрактно, вот так: