Это близко к тому, что вы хотели?
#include <vector>
#include <utility>
#include <memory>
struct Foo
{
int member_func();
};
template <typename Vec>
void func(const Vec& vec) {
using ret_type = decltype(std::declval<typename Vec::value_type>()->member_func());
std::vector< ret_type > local_vec;
}
int main()
{
std::vector<std::unique_ptr<Foo>> v;
func(v);
}
Демонстрация: https://godbolt.org/g/dJkSf1
Объяснение:
std::declval<typename Vec::value_type>()
создает ссылку на unique_ptr (который должен использоваться в невычисленном контексте). Затем мы берем decltype вызова generated_reference->member_function()
.
Это будет тот же тип, что и результат vec[0]->member_func()
Действительно, мы могли бы написать это так:
template <typename Vec>
void func(const Vec& vec) {
using ret_type = decltype(vec.at(0)->member_func());
std::vector< ret_type > local_vec;
}
Что может быть более выразительным и универсальным (теперь Vec
может быть любым типом, похожим на вектор и содержащим указатели на Foo
)
Более того, чем более общий подход к выводу мы делаем, тем более общей становится наша func
функция:
#include <vector>
#include <utility>
#include <memory>
#include <set>
#include <iterator>
struct Foo
{
int member_func();
};
template <typename Vec>
void func(const Vec& vec) {
using ret_type = decltype((*std::begin(vec))->member_func());
std::vector< ret_type > local_vec;
}
int main()
{
std::vector<std::unique_ptr<Foo>> v;
func(v);
func(std::array<std::unique_ptr<Foo>, 10> { });
Foo* foos[] = { nullptr, nullptr };
func(foos);
func(std::set<std::shared_ptr<Foo>, std::owner_less<>> {});
}
Примечание
Этот код предполагает, что return_type для Foo::member_func
не является ссылочным типом.
Если это возможно, нам нужно решить, использовали ли мы метапрограммирование для:
а) преобразовать ссылочные типы в std::reference_wrapper, чтобы их можно было хранить в векторе, или
б) преобразовать ссылочные типы в основные типы с помощью std::decay
, что приведет к созданию копий.
person
Richard Hodges
schedule
06.06.2018
...::element_type
).std::declval
, используемый в ответе, представляет собой идиоматический способ получить экземпляр типа в невычисленном (например,decltype
) контексте. - person Max Langhof   schedule 06.06.2018