这接近你想要的吗?
#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>()
生成对唯一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<>> {});
}
注释
此代码假定返回类型为
Foo::member_func
不是引用类型。
如果有可能,我们需要决定是否使用元编程来:
a)将引用类型转换为STD::RealthyTyWrpector,以便它们可以存储在向量中,或者
b)使用
std::decay
,这将导致复制。