How can I get the correct type T for the following function to_vector?
template<typename K> struct A { K* p; size_t n; std::string foo; };
template<typename K> struct B { K* p; size_t n; float bar[3]; };
template<typename X>
std::vector<T> to_vector(const X& x) { // what is T?
return std::vector<T>(x.p, x.p+x.n);
}
I tried with decltype(*std::declval<X>().p) but this results in error: forming pointer to reference type ‘float&’ for the following example:
A<float> a = { new float[10], 10, "hello" };
std::vector<float> v = to_vector(a);
This is part of some bigger code and there are more types like A and B. But all have a pointer p and a length n.
You can probably use
typename std::decay<decltype(*X::p)>::type
for T because decltype is an unevaluated context and hence X::p is legal here. Also, std::decay seems like a good fit as it combines std::remove_reference with std::remove_cv.
You are on the right track, you just need to use appropriate utility to get rid of the pointer/reference.
There is std::remove_reference, which you can use like:
typename std::remove_reference<decltype(*std::declval<X>().p)>::type
but it's a bit simpler to std::remove_pointer instead:
typename std::remove_pointer<decltype(std::declval<X>().p)>::type
(see, the * is gone, otherwise the same).
You might want to throw in std::remove_cv into the mix if the pointer might be cv-qualified, because vector elements shouldn't be.
As noted in the other, now deleted answer, you can write x.p instead of std::declval<X>().p if you use the trailing return type declaration:
template <typename X>
auto to_vector(const X& x) ->
std::vector<typename std::remove_pointer<decltype(x.p)>::type>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With