Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 避免打开类型以允许不断折叠_C++_Templates_Constantfolding - Fatal编程技术网

C++ 避免打开类型以允许不断折叠

C++ 避免打开类型以允许不断折叠,c++,templates,constantfolding,C++,Templates,Constantfolding,我试图找到一个类层次结构,它允许为处理器寄存器和操作实现占位符。它还应该允许在运行时折叠常量。为了简单起见,我只看一个运算,这里是乘法。占位符和常量应统一访问,即具有公共基类 下面的代码定义了以下类: A类:占位符(寄存器)和常量的基类 B类:寄存器的占位符(其结构包含其名称) C类:所有常数的基数 类CI:int常数 #include <iostream> #include <memory> #include <cassert> class A { pub

我试图找到一个类层次结构,它允许为处理器寄存器和操作实现占位符。它还应该允许在运行时折叠常量。为了简单起见,我只看一个运算,这里是乘法。占位符和常量应统一访问,即具有公共基类

下面的代码定义了以下类:

A类
:占位符(寄存器)和常量的基类

B类
:寄存器的占位符(其结构包含其名称)

C类
:所有常数的基数

类CI
int
常数

#include <iostream>
#include <memory>
#include <cassert>

class A {
public:
  virtual ~A(){}
};

class B : public A {
};

class C : public A {};

class CI : public C {
public:
  typedef int Type_t;
  int getValue() {return 1;}
};

class CF : public C {
public:
  typedef float Type_t;
  float getValue() {return 1.1;}
};




typedef std::shared_ptr<A> Aptr;
typedef std::shared_ptr<B> Bptr;
typedef std::shared_ptr<C> Cptr;
typedef std::shared_ptr<CI> CIptr;
typedef std::shared_ptr<CF> CFptr;


template<class T, class T2> struct promote {};
template<> struct promote<float,int>   { typedef float Type_t; };
template<> struct promote<float,float> { typedef float Type_t; };
template<> struct promote<int,float>   { typedef float Type_t; };
template<> struct promote<int,int  >   { typedef int   Type_t; };


template<class T1, class T2>
typename promote<typename T1::element_type::Type_t,
         typename T2::element_type::Type_t>::Type_t
mul_const( const T1& c1 , const T2& c2 )
{
  std::cout << c1->getValue() * c2->getValue() << "\n";
  return c1->getValue() * c2->getValue();
}



template<class T>
std::shared_ptr<T> get(const Aptr& pA) {
  return std::dynamic_pointer_cast< T >( pA );
}


Aptr create_A(float f) { return std::make_shared<A>(); }
Aptr create_A(int i)   { return std::make_shared<A>(); }


Aptr mul_const( const Cptr& cp1 , const Cptr& cp2 )
{
  if (auto c1 = get<CI>(cp1))
    if (auto c2 = get<CF>(cp2)) {
      return create_A( mul_const(c1,c2) );
    }
  if (auto c1 = get<CF>(cp1))
    if (auto c2 = get<CI>(cp2)) {
      return create_A( mul_const(c1,c2) );
    }
  if (auto c1 = get<CI>(cp1))
    if (auto c2 = get<CI>(cp2)) {
      return create_A( mul_const(c1,c2) );
    }
  if (auto c1 = get<CF>(cp1))
    if (auto c2 = get<CF>(cp2)) {
      return create_A( mul_const(c1,c2) );
    }
  assert(!"oops");
}



Aptr mul( const Aptr& pA1, const Aptr& pA2 ) 
{
  if (auto c1 = get<C>(pA1))
    if (auto c2 = get<C>(pA2)) 
      {
    return mul_const(c1,c2);
      }
}


int main()
{
  Aptr pA1( new CF );
  Aptr pA2( new CI );

  Aptr result = mul( pA1, pA2 );
}
类CF
浮动
常数

#include <iostream>
#include <memory>
#include <cassert>

class A {
public:
  virtual ~A(){}
};

class B : public A {
};

class C : public A {};

class CI : public C {
public:
  typedef int Type_t;
  int getValue() {return 1;}
};

class CF : public C {
public:
  typedef float Type_t;
  float getValue() {return 1.1;}
};




typedef std::shared_ptr<A> Aptr;
typedef std::shared_ptr<B> Bptr;
typedef std::shared_ptr<C> Cptr;
typedef std::shared_ptr<CI> CIptr;
typedef std::shared_ptr<CF> CFptr;


template<class T, class T2> struct promote {};
template<> struct promote<float,int>   { typedef float Type_t; };
template<> struct promote<float,float> { typedef float Type_t; };
template<> struct promote<int,float>   { typedef float Type_t; };
template<> struct promote<int,int  >   { typedef int   Type_t; };


template<class T1, class T2>
typename promote<typename T1::element_type::Type_t,
         typename T2::element_type::Type_t>::Type_t
mul_const( const T1& c1 , const T2& c2 )
{
  std::cout << c1->getValue() * c2->getValue() << "\n";
  return c1->getValue() * c2->getValue();
}



template<class T>
std::shared_ptr<T> get(const Aptr& pA) {
  return std::dynamic_pointer_cast< T >( pA );
}


Aptr create_A(float f) { return std::make_shared<A>(); }
Aptr create_A(int i)   { return std::make_shared<A>(); }


Aptr mul_const( const Cptr& cp1 , const Cptr& cp2 )
{
  if (auto c1 = get<CI>(cp1))
    if (auto c2 = get<CF>(cp2)) {
      return create_A( mul_const(c1,c2) );
    }
  if (auto c1 = get<CF>(cp1))
    if (auto c2 = get<CI>(cp2)) {
      return create_A( mul_const(c1,c2) );
    }
  if (auto c1 = get<CI>(cp1))
    if (auto c2 = get<CI>(cp2)) {
      return create_A( mul_const(c1,c2) );
    }
  if (auto c1 = get<CF>(cp1))
    if (auto c2 = get<CF>(cp2)) {
      return create_A( mul_const(c1,c2) );
    }
  assert(!"oops");
}



Aptr mul( const Aptr& pA1, const Aptr& pA2 ) 
{
  if (auto c1 = get<C>(pA1))
    if (auto c2 = get<C>(pA2)) 
      {
    return mul_const(c1,c2);
      }
}


int main()
{
  Aptr pA1( new CF );
  Aptr pA2( new CI );

  Aptr result = mul( pA1, pA2 );
}
#包括
#包括
#包括
甲级{
公众:
虚拟~A(){}
};
B类:公共A{
};
C类:公共A{};
CI类:公共C类{
公众:
typedef int Type_t;
int getValue(){return 1;}
};
CF类:公共C类{
公众:
类型定义浮点数类型\u t;
float getValue(){return 1.1;}
};
typedef std::共享\u ptr Aptr;
typedef std::共享\u ptr Bptr;
typedef std::shared_ptr Cptr;
typedef std::shared_ptr CIptr;
typedef std::共享\u ptr CFptr;
模板结构升级{};
模板结构升级{typedef float Type_t;};
模板结构升级{typedef float Type_t;};
模板结构升级{typedef float Type_t;};
模板结构升级{typedef int Type_t;};
模板
typename升级::Type\u t
多常数(常数T1和c1、常数T2和c2)
{
std::cout getValue()*c2->getValue()getValue()*c2->getValue();
}
模板
标准::共享ptr get(const Aptr&pA){
返回标准::动态指针投射(pA);
}
Aptr create_A(float f){return std::make_shared();}
Aptr create_A(int i){return std::make_shared();}
Aptr多常数(常数Cptr和cp1、常数Cptr和cp2)
{
如果(自动c1=获取(cp1))
如果(自动c2=获取(cp2)){
返回create_A(mul_const(c1,c2));
}
如果(自动c1=获取(cp1))
如果(自动c2=获取(cp2)){
返回create_A(mul_const(c1,c2));
}
如果(自动c1=获取(cp1))
如果(自动c2=获取(cp2)){
返回create_A(mul_const(c1,c2));
}
如果(自动c1=获取(cp1))
如果(自动c2=获取(cp2)){
返回create_A(mul_const(c1,c2));
}
断言(!“oops”);
}
Aptr mul(常数Aptr和pA1、常数Aptr和pA2)
{
如果(自动c1=get(pA1))
如果(自动c2=获取(pA2))
{
返回多常数(c1,c2);
}
}
int main()
{
Aptr pA1(新CF);
Aptr pA2(新CI);
Aptr结果=mul(pA1,pA2);
}

以上代码的问题是函数
Aptr mul_const(const Cptr&cp1,const Cptr&cp2)
。它基本上包含所有可能的常量类型组合的类型切换。它可以工作,但我想知道这是否可以更优雅地完成?

我想你可以像编译器那样做,当一个参数是float时,将另一个参数转换为float。您可能需要一个新函数来进行转换,还需要一个“isFloat”(或“isInt”)。我不相信它能给你带来这么多好处,真的

// Add two virtual member functions here:
class C : public A {
    public:
       virtual bool isInt() = 0;
       virtual float getAsFloat() = 0;
};
然后实施:

class CI : public C {
public:
  typedef int Type_t;
  int getValue() {return 1;}
  float getAsFloat() { return getValue(); }
  bool isInt() { return true; }
};

class CF : public C {
public:
  typedef float Type_t;
  float getValue() {return 1.1;}
  float getAsFloat() { return getValue(); }
  bool isInt() { return false; }
};
现在,您的mul_const变为:

Aptr mul_const( const Cptr& cp1 , const Cptr& cp2 )
{
  if (cp1.isInt() && cp2.isInt())
  {
     CIptr c1 = get<CI>(cp1));
     CIptr c2 = get<CI>(cp2));
     std::cout << c1->getValue() * c2->getValue() << "\n";
     return CIptr(c1->getValue() * c2->getValue());
  }
  else
  {
     std::cout << cp1->getAsFloat() * cp2->getAsFloat() << "\n";
     return CFptr(cp2->getAsFloat() * cp2->getAsFloat());
  }
  // This becomes unreachable... Probably OK to delete.
  assert(!"oops");
}
Aptr多常数(常数Cptr&cp1,常数Cptr&cp2)
{
if(cp1.isInt()&&cp2.isInt())
{
CIptr c1=get(cp1));
CIptr c2=get(cp2));
std::cout getValue()*c2->getValue()getValue()*c2->getValue());
}
其他的
{
std::cout getAsFloat()*cp2->getAsFloat()getAsFloat()*cp2->getAsFloat());
}
//这将变得无法访问…可能可以删除。
断言(!“oops”);
}

[我认为可以删除一些模板部分…]

运行时不断折叠
?这是一个编译时的概念,您可以根据编译时的类型为它生成指令。当然,这些值只在运行时可用。您可以看到
CI
包含
int
。这是其结构的一部分。(为了简单起见,这里设置为1)这里的问题是从运行时切换到编译时多态性。对于给定的类层次结构,您需要这个。问题是它能做得更好吗?它的优点是它消除了对
struct-promote
的需要。是的,我认为这也是一个好处。我认为这也让代码更容易阅读[我很快就会迷失在复杂的模板代码中-可能是因为我没有做过那么多的模板编码…]