У меня есть шаблон шаблонной функции template< template< class > class Timg, class T > Timg< T > foo(), для которой компилятор не может выводить типы. Я могу вызвать эту функцию с помощью foo< object, T >(), где object - это класс шаблона. Я хотел бы иметь возможность вызывать эту функцию с помощью decltype или чего-то подобного.
Вот пример: первый файл - header.h
template< class T >
class object
{
};
template< template< class > class Timg, class T >
Timg< T > foo()
{
return Timg< T >();
}
Второй файл - main.cpp
#include "header.h"
int main()
{
object< float > o;
auto l_return = foo< object, float >(); // OK
auto l_return2 = foo< decltype(o), float >(); // What I would like to achieve
return 0;
}
Проблема здесь в том, что decltype(o) возвращает object< float >, но я бы хотел иметь только object.
Как я могу вывести тип из переменной o, чтобы передать его в качестве параметра шаблона для функции foo?





object - это шаблон класса, а не тип. Типом является только экземпляр шаблона класса. object<float> - это тип. Сама шаблона нет, это шаблон…
Я не знаю, как напрямую вывести исходный шаблон, из которого был создан тип. Что вы могли бы сделать, так это определить шаблон вспомогательного класса и частично специализироваться, чтобы соответствовать случаю, когда тип параметра является экземпляром шаблона с одним параметром типа. Таким образом, вы можете определить как шаблон, так и тип параметра данного экземпляра object. Внутри этого вспомогательного шаблона у вас может быть шаблон псевдонима члена, который снова предоставит вам экземпляр object, а также псевдоним для пересылки типа параметра.
template <class T>
struct deduce_object_template;
template <template <class> class O, class V>
struct deduce_object_template<O<V>>
{
template <class T>
using object_t = O<T>;
using type = V;
};
а затем используйте это для вызова foo вот так:
foo<deduce_object_template<T>::template object_t, typename deduce_object_template<T>::type>();
Однако я бы серьезно задался вопросом, нет ли более простого способа добиться того, чего вы хотите достичь. Вам действительно нужно определить шаблон и тип аргумента? Если все, что вам нужно, это создать объект с любым параметром типа, почему бы просто не определить второй шаблон
template <class Timg>
Timg foo()
{
return Timg();
}
а вызвать в foo<decltype(o)>();?
В этом случае не могли бы вы просто вывести Timg из параметра функции вместо того, чтобы явно указывать аргументы: Timg<bla> foo(const Timg<T>& in) {...}?
В вашем примере это действительно работает, потому что T - это тип параметра функции. В моем контексте T находится в возвращаемом типе, поэтому он больше похож на template <template <class> class Timg, class T> Timg<T> foo(const Timg<int>& in) {...}, который не может быть выведен компилятором.
В этом случае просто измените порядок параметров вашего шаблона на template <class T, template <class> class Timg>. Затем вы можете записать foo<float>(blub); и вывести Timg из blub и только явно указать аргумент для типа возвращаемого значения.
Это правда, я думал об этом. Однако более естественно писать параметры шаблона в том порядке, в котором они появляются (это может быть даже в правилах кодирования моей компании), и, отвечая на этот вопрос, я предполагаю, что в ближайшие дни мне придется написать более сложные оболочки.
Спасибо, это умный обходной путь! Я привел простой пример. Моя функция больше похожа на
Timg< Tout > foo(Timg< Tin> x), поэтому я не использую второй вариант только с одним параметром шаблона.