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