c – 内部类型变化取决于父类

前端之家收集整理的这篇文章主要介绍了c – 内部类型变化取决于父类前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我放弃了,请帮忙解释一下这个行为.下面我给出的例子是我能想到的最简单的例子,但是总结了这个问题(在Cygwin上使用g 4.9.2,启用了c14).我想创建一个类似于std :: mem_fn的类.这是我的课:
template <class R,class T,R(T::*P)() const >
struct property {

    static R get(const T& t) {
        return (t.*P)();
    }
};

其中R是返回类型,T是我感兴趣的对象的类型.第三个模板参数是一个指向成员函数的指针.到现在为止还挺好.

然后我创建一个简单的类,它保存一个整数如下

class data_class {

public:

    unsigned get_data() const {
        return m_data;
    }

private:
    unsigned m_data;
};

这是将在以前显示属性类中使用的类.

现在我创建了从data_class继承的两个类,如下所示

struct my_classA
: public data_class {

    using data = property<unsigned,data_class,&data_class::get_data>;
};

//same as my_classA,only templated
template <int I>
struct my_classB
: public data_class {

    using data = property<unsigned,&data_class::get_data>;
};

它们具有完全相同的内部typedef,但是my_classB是模板化的.以下类型在理论上应该是一样的:

using target_t = property<unsigned,&data_class::get_data>;
using test1_t = typename my_classA::data;
using test2_t = typename my_classB<1>::data;

但是我的编译器说只有test1_t和target_t是一样的.显然为test2_t推出的类型

property<unsigned int,(& data_class::get_data)> >

这个类型在指向成员函数的指针周围有这些括号.为什么test2_t与target_t不一样?这是完整的代码,以防您想在系统上尝试.任何帮助深表感谢.

#include <type_traits>

class data_class {

public:

    unsigned get_data() const {
        return m_data;
    }

private:
    unsigned m_data;
};

//takes return type,class type,and a pointer to member function
//the get function takes an object as argument and uses the above pointer to call the member function
template <class R,R(T::*P)() const >
struct property {

    static R get(const T& t) {
        return (t.*P)();
    }
};

struct my_classA
: public data_class {

    using data = property<unsigned,&data_class::get_data>;
};

//used to produce informative errors
template <class T>
struct what_is;

//all 3 types below should,in theory,be the same
//but g++ says that test2_t is different
using target_t = property<unsigned,&data_class::get_data>;
using test1_t = typename my_classA::data;
using test2_t = typename my_classB<1>::data;

static_assert(std::is_same<target_t,test1_t>::value,""); //this passes
static_assert(std::is_same<target_t,test2_t>::value,""); //this does not

int main() {

    what_is<test1_t> t1;
    what_is<test2_t> t2;
}

解决方法

我用c 11运行你的代码,因为我对C14还不太熟悉.但是我更换的是使用typedef的(别名),并简化了一些代码.没有什么可以影响其输出.

通过在继承的classB模板中添加一个typename T来获得所需的结果,当实例化时,它将用T代替R,所以在这种情况下是“unsigned”.

#include <iostream>
#include <type_traits>

template <typename R,typename T,R(T::*P)() const>
struct property
{
    static R get(const T& t)
    {
        return (t.*P)();
    }
};


struct data_class
{
    private:
        unsigned m_data;

    public:
        unsigned get_data() const
        {
            return m_data;
        }
};

struct my_classA : public data_class
{
    typedef property<unsigned,&data_class::get_data> data;
};

template <typename T,int>
struct my_classB : public data_class
{
    typedef property<T,&data_class::get_data> data;
};


int main()
{

    typedef typename my_classA::data normClassA;
    typedef typename my_classB<unsigned,1>::data tmplClassB;

    std::cout<< std::is_same< property<unsigned,&data_class::get_data>,normClassA >::value <<std::endl;
    std::cout<< std::is_same< property<unsigned,tmplClassB >::value <<std::endl;

}

结果是这样的:

~$g++ -std=c++11 test.cpp
~$./a.out 
1
1

我认为该问题与类模板实例化标准有关,因为当我最初尝试打印两个类的sizeof时,my_classA :: data返回1,但是my_classB< 1> :: data以compiller错误结束.为什么会发生这种情况,我还是很模糊的.在技​​术上它应该已经实例化了类模板很好.也许这是classB模板中虚拟实例化的属性.我会再看看这个,但如果你找到答案,请张贴.这是一个有趣的!

编辑:原始代码在Cygwin GCC 4.8.2中正常工作.结果是1和1.也许这只是一个gcc4.9.2编译器问题.

原文链接:https://www.f2er.com/c/112897.html

猜你在找的C&C++相关文章