C++ 如何动态确定用于参数化模板的类型并进行比较

C++ 如何动态确定用于参数化模板的类型并进行比较,c++,types,type-conversion,C++,Types,Type Conversion,如果基于一个或多个类型参数创建类模板,那么在运行时如何查询这些类型 例如: template <typename T> class Foo { public: typedef T TypeT; Foo() {} // assume i is in range void set(size_t i, T value) { store[i] = value; } T get(size_t i) { return store[i]; } void fast_c

如果基于一个或多个类型参数创建类模板,那么在运行时如何查询这些类型

例如:

template <typename T>
class Foo {
 public:
  typedef T TypeT;

  Foo() {}

  // assume i is in range
  void set(size_t i, T value) { store[i] = value; }
  T get(size_t i) { return store[i]; }

  void fast_copy(T* dest) { memcpy(dest, store, 100 * size_of(T)); }

  // ugly public data member
  T store[100];
};


void main() {
  Foo<double> fd;
  Foo<int> fi;

  // this is not C++!
  if (fd::TypeT == fi::TypeT) {

    // do a fast copy since the types match
    fd.fast_copy(fi.store);

  } else {

    // do a slower item by copy since the types don't match
    // and let the runtime perform the type conversion:
    for (size_t i = 0; i < 100; ++i) {
      fi.set(i, static_cast<fd::TypeT>(fd.get(i)));
    }
  }
}

您可以使用重载。将此添加到您的类中

void copy(T & dest)
{
   fast_copy(&dest):
}

template<class U>
void copy(U & dest)
{
   for (size_t i = 0; i < 100; ++i) {
      dest.set(i, static_cast<TypeT>(get(i)));
}
无效副本(T&dest)
{
快速拷贝(&dest):
}
模板
无效副本(U&dest)
{
对于(尺寸i=0;i<100;++i){
目标集(i,静态施法(get(i));
}

PS:更多的C++方式是定义复制构造函数或赋值运算符< /P> 编辑:如果你想动态mke的东西更多态

struct BaseDest
{
   virtual void assign(const double * v, size_t cnt) = 0;
   virtual void assign(const float * v, size_t cnt) = 0;
//etc
}

template<class T>
struct DestImpl
{
   void assign(const double * v, size_t cnt)
   {
       assign_impl(v, cnt);
   }
   void assign(const float * v, size_t cnt)
   {
       assign_impl(v, cnt);
   }

   template<class U>
   void assign_impl(const U * v, size_t cnt)
   {
      for (size_t i = 0; i < cnt; ++i) {
         set(i, static_cast<T>(v[i])));
   }

   template<>
   void assign_impl<T>(const T * v, size_t cnt)
   {
      fast_copy(v, cnt);
   }
//stuff
}

struct Source
{
//blah
   template<class T>
   void set(const T * v, size_t cnt)
   {
     dest_->set(v, cnt);
   }

//blah
}
struct BaseDest
{
虚拟空位分配(常数双*v,大小=0;
虚空分配(常量浮点*v,大小cnt)=0;
//等
}
模板
结构目标
{
无效分配(常数双*v,大小为cnt)
{
分配_impl(v,cnt);
}
无效分配(常量浮点*v,大小为cnt)
{
分配_impl(v,cnt);
}
模板
无效分配(常数U*v,大小C)
{
对于(尺寸i=0;i设置(v,cnt);
}
//废话
}

在这里,您可以使用std::is_same,或者如果您想要运行时-typeid(T)。对于相同和不同的类型,您将重载复制。如果您想要将A、B、C中的任何一个复制到A、B、C中的任何一个,您需要有九段独立的代码。在运行时查询类型没有意义,因为所有类型在编译时都已知(除非存在继承,但这不是您的情况)。尝试提出一个真正需要查询类型的用例(提示:不太可能;如果您正在编写模板,最多需要一个编译时查询)。当然,你的9段代码可能是同一模板的实例化,因此你不必全部手工编写。对不起,你本来应该是t的。我最初把它作为U,但改为t,错过了几个实例-我的错误。我编辑了这个问题。谢谢你的回答,但这都是静态的,不是吗?我需要的是我这是一种在运行时根据两个对象之间的动态关联选择正确版本的
copy
的方法。请参阅我发布的代码“EDIT 2”。谢谢,这看起来很简单-这类似于n.m.在问题注释中提到的所谓的双重分派吗?或者这会涉及给DestImpl对象一个
对象并根据
的类型调用重载成员函数吗?顺便说一句,DestImpl意味着从B公开继承Aseest,是这样吗?我在这里遇到了一个问题-似乎在类/结构中专门化函数模板是不合法的。解决方案是将assign_impl专门化移到非成员函数中(如果他们需要访问DestImpl的数据成员,让他们成为朋友)?关于,我认为我已经找到了解决方案,但我的编译器(clang)警告我,模板参数永远无法推导。我在这里将其拆分为一个新问题:
struct BaseDest
{
   virtual void assign(const double * v, size_t cnt) = 0;
   virtual void assign(const float * v, size_t cnt) = 0;
//etc
}

template<class T>
struct DestImpl
{
   void assign(const double * v, size_t cnt)
   {
       assign_impl(v, cnt);
   }
   void assign(const float * v, size_t cnt)
   {
       assign_impl(v, cnt);
   }

   template<class U>
   void assign_impl(const U * v, size_t cnt)
   {
      for (size_t i = 0; i < cnt; ++i) {
         set(i, static_cast<T>(v[i])));
   }

   template<>
   void assign_impl<T>(const T * v, size_t cnt)
   {
      fast_copy(v, cnt);
   }
//stuff
}

struct Source
{
//blah
   template<class T>
   void set(const T * v, size_t cnt)
   {
     dest_->set(v, cnt);
   }

//blah
}