【问题标题】:get type of member memberpointer points to获取成员 memberpointer 指向的类型
【发布时间】:2014-05-14 13:35:19
【问题描述】:

我想提取成员指针指向的成员的类型。

template<someType myClass::*member>
void demo(myClass& instance, void* ptr) {
    instance.*member = *reinterpret_cast<someType*>(ptr);  // can the someType in this line be deduced from member?
}

我尝试按照 cmets 中的建议使用 decltype,但是我对此有疑问:

instance.*member= static_cast<decltype(instance.*member)>((*buffer)[offset]);

buffer 是 std::shared_ptr&lt;std::vector&lt;uint8_t&gt;&gt;,
someType 是 uint32_t

我收到以下错误消息:

错误:来自类型的无效 static_cast ‘__gnu_cxx::__alloc_traits >::value_type {aka unsigned char}' 输入'uint32_t& {aka unsigned int&}'

据我了解,decltype(instance.*member) 将member 定义为uint32_t instance::*member 会产生一个引用 uint32_t&amp; 而不是uint32_t。我试图按值传递实例,但错误仍然存​​在。我知道std::remove_reference 但是,我不明白引用是如何出现的。

如果我可以在没有类实例的情况下提取someType,那将是一个进一步的改进。但是我不知道如何实现这一点,而我可以通过 std lib 获得没有指针的类:

template <T*>
struct removePointer {
  typedef T type;
}

我不知道如何以我可以在不知道课程的情况下获得课程的someType 部分的形式编写此内容。我可以写类似下面的东西,但是我仍然必须明确地传递类 naem 和 typename,有没有办法自动提取这些?此外,以下内容首先无法编译(http://ideone.com/8VlKO4): #包括 使用命名空间标准;

template <class C,typename T, T C::*v>
struct getPointerType {
typedef T type;
};

class Test {
int value;
};

int main() {
int Test::*member=nullptr;
cout << typeid(getPointerType<Test, int, decltype(member)>::type) << std::endl;
return 0;
}

【问题讨论】:

  • 在 c++11 上,您可以使用 decltype() 显式推断所需的类型。如果你没有启用 c++11,你可以用typeof/__typeof__ 下车。
  • @oakad 你能帮我处理 decltype 部分吗?我更新了问题以显示我在使用 decltype 时遇到的问题,并添加了关于使用模板的宣传,但是我担心使用模板的想法行不通。

标签: c++ types member-pointers


【解决方案1】:

坦率地说,有点难以理解您想要实现的目标,因此我将专注于更新的部分。

显然,您不能将类型(派生自decltype)作为值参数传递给模板。此外,您不能将非 constexpr 值作为模板参数传递(因此您不能只将 member 变量粘贴到模板参数中并期望它编译)。

但是,您可以依靠编译器来推断出正确的函数来调用非 costexpr 变量:

template <class C, typename T>
T getPointerType(T C::*v);

class Test {
    int value;
};

int main() {
    int Test::*member=nullptr;
    cout << typeid(decltype(member)).name() << std::endl;
    cout << typeid(decltype(getPointerType(member))).name() << std::endl;
    return 0;
}

上面将打印:

M4Testi //int Test::*
i       //int

当然,更可能“滥用”模板替换:

template <typename M>
struct getPointerType {
   template <typename C, typename T>
   static T get_type(T C::*v);

   typedef decltype(get_type(static_cast<M>(nullptr))) type;
};

class Test {
    int value;
};

int main() {
    int Test::*member=nullptr;
    cout << typeid(getPointerType<decltype(member)>::type).name() << std::endl;
    return 0;
}

输出将是预期的“i”。

【讨论】:

  • 这正是我想要的。如果我理解你,没有办法想出像getPointerType&lt;member&gt;::type 语法这样的库,因为member 不是const。有没有可能达到getPointerType&lt;decltype(member)&gt;::type?或者getPointerType(member).type(我试过这个:“template struct getPointerType { getPointerType(TC::*v) {} typedef T type; };”,但是这会导致模板参数的错误不见了)
  • 好的,编辑帖子以包含getPointerType&lt;decltype(member)&gt;::type。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 2018-03-24
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
相关资源
最近更新 更多