Dan*_*vil 7 c++ templates c++11
如何获得T以下功能的正确类型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);
}
Run Code Online (Sandbox Code Playgroud)
我尝试过,decltype(*std::declval<X>().p)但这导致error: forming pointer to reference type ‘float&’以下示例:
A<float> a = { new float[10], 10, "hello" };
std::vector<float> v = to_vector(a);
Run Code Online (Sandbox Code Playgroud)
这是一些更大的代码的一部分,有更多的类型,如A和B.但都有指针p和长度n.
你可以使用
typename std::decay<decltype(*X::p)>::type
Run Code Online (Sandbox Code Playgroud)
对于T因为decltype是未计算的背景下,因此X::p是合法的在这里.而且,std::decay似乎是一个不错的选择,因为它结合std::remove_reference使用std::remove_cv.
你是在正确的轨道上,你只需要使用适当的实用程序来摆脱指针/引用.
有std::remove_reference,你可以使用如下:
typename std::remove_reference<decltype(*std::declval<X>().p)>::type
Run Code Online (Sandbox Code Playgroud)
但它更简单一点std::remove_pointer:
typename std::remove_pointer<decltype(std::declval<X>().p)>::type
Run Code Online (Sandbox Code Playgroud)
(看,*已经消失,否则相同).
如果指针可能是cv -qualified,你可能想把std :: remove_cv放入混合中,因为vector元素不应该是.
如另一个所述,现在已删除的答案,您可以编写x.p而不是std::declval<X>().p使用尾随返回类型声明:
template <typename X>
auto to_vector(const X& x) ->
std::vector<typename std::remove_pointer<decltype(x.p)>::type>
Run Code Online (Sandbox Code Playgroud)
小智 5
这个答案现在几乎已经过时了。
template<typename X, typename T = typename std::remove_reference<decltype(*X().p)>::type>
std::vector<T> to_vector(const X& x)
{
return std::vector<T>
(x.p, x.p+x.n);
}
Run Code Online (Sandbox Code Playgroud)