如何获取函数返回类型的解除引用类型的模板成员

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.

Dan*_*rey 6

你可以使用

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.


Jan*_*dec 5

你是在正确的轨道上,你只需要使用适当的实用程序来摆脱指针/引用.

有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)