Страницы

Поиск по вопросам

пятница, 28 июня 2019 г.

Cast оператор и шаблонные функции

Предположим у меня есть два шаблонных типа: основной, который будет везде использоваться и вспомогательный, для нужд реализации. И я хочу объявить функцию которая принимает основной тип.
template struct Usefull;
template struct Helper { Helper(T i) : v(i) {}
T v;
operator Usefull() { return Usefull(v); } };
template struct Usefull { Usefull(T i) : h(i) {}
Helper h; void print() { std::cout << h.v << std::endl; } };
template void foo(Usefull b) { b.print(); }
И я хочу использовать это вот так:
int main() { Usefull x(42); foo(x.h); }
Но возникает ошибка компиляции:
template argument deduction/substitution failed: 'Helper' is not derived from 'Usefull'
Использовать static_cast> не желательно, менять или перегружать foo тоже не охота. Есть ли какие-то еще способы заставить Helper хорошо и неявно преобразовываться в Useful?
То есть пользователь не должен знать с чем он работает на самом деле, Useful и Helper для него должны вести себя одинаково. Может здесь можно использовать наследование, но я не приложу ума как это организовать.


Ответ

Согласно примечанию к параграфу №4 в разделе 14.8.2.1 Deducing template arguments from a function call стандарта C++
[ Note: as specified in 14.8.1, implicit conversions will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter contains no template-parameters that participate in template argument deduction. Such conversions are also allowed, in addition to the ones described in the preceding list. —end note ]
В вашем случае соответствующий параметр функции содержит шаблонный параметр, который участвует в выведении шаблонного аргумента. Поэтому вам придется явно указать шаблонный аргумент или явно использовать приведение типов. Например
Usefull x(42);
foo(x.h); foo( static_cast>( x.h ));

Комментариев нет:

Отправить комментарий