【问题标题】:Using the type of a class member of the first type in a template在模板中使用第一个类型的类成员的类型
【发布时间】:2020-03-24 13:51:16
【问题描述】:

搜索我发现this answer 的站点,用于获取类中成员的类型。 基于此,我制作了以下成功编译的示例。

#include <iostream>
#include <stdio.h>
#include <string>

using namespace std;


class sig_class_t{
public:
    int field;
};

class usig_class_t{
public:
    unsigned int field;
};

template <class T, class M> M get_member_type(M T:: *);

template<typename my_class = sig_class_t, typename my_type = decltype(get_member_type(&my_class::field))>
class Tricky{
    my_type it;
public:
    my_type get_it();
    void set_it(my_type value);
};

template<typename my_class, typename my_type>
my_type Tricky<my_class,my_type>::get_it(){
    return it;
}

template<typename my_class, typename my_type>
void Tricky<my_class,my_type>::set_it(my_type value){
    it = value;
}

int main(int argc, char *argv[])
{
    return 0;
}

get_member_type 如何判断给定指针的类型?
这段代码看起来很复杂,如果我不明白它是如何工作的,我会感到不舒服。

【问题讨论】:

  • 例如,另一种可能是decltype(std::declval&lt;my_class&gt;().field)

标签: c++ templates decltype


【解决方案1】:

template<typename my_class = sig_class_t, 
         typename my_type = decltype(get_member_type(&my_class::field))>
class Tricky{
    my_type it;
public:
    my_type get_it();
    void set_it(my_type value);
};

您将&amp;my_class::field 传递给get_member_type&amp;my_class::field 是指向field 成员myclass 的指针,因此它具有类型

decltype(my_class::field) myclass::*

或者用英语说,myclass 成员指针指向 field 成员的类型。默认情况下(因为它使用sig_class_t)是

int sig_class_t::*

为什么你把它传递给

template <class T, class M> M get_member_type(M T:: *);

M 被推断为intT 被推断为sig_class_t。然后该函数“返回”一个M 类型的对象,因此decltype(get_member_type(&amp;my_class::field)) 解析为M(默认情况下为int),这就是my_type 被推断为指针指向的类型的方式.

【讨论】:

  • 唷.. 想不通它并不容易.. 几乎明白了,但是get_member_type 令牌怎么就消失了?
  • @DavidTóth 因为decltypeget_member_type 就是所谓的元函数。那是一个接受事物并返回事物的函数,并且您在模板上下文中使用该返回类型。在这种情况下,decltype 实际上并没有调用该函数,而是查看如果有它会返回什么类型,然后返回该类型。
  • 好的,点击成功!谢谢!
【解决方案2】:

虽然这不是对您问题的直接回答,但我觉得这个表达更容易理解:

decltype(std::declval&lt;my_class&gt;().field)

std::declval&lt;my_class&gt;() 部分返回一个“虚拟”my_class 对象,因此我们可以在其上使用.field。而这个子表达式被包裹在decltype 中,这将给出field 的类型。

(注意,declval 只能用在未计算的上下文中。decltype 的参数就是这样的上下文。)

【讨论】:

    猜你喜欢
    • 2012-05-25
    • 2021-07-25
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    相关资源
    最近更新 更多