从虚拟 class 转换派生模板 class
Casting derived template class from virtual class
在我的代码中,我有一个抽象 class 和 ~8 个子 classes。我想问一下,在C++中是否可以将typename
和return转换为调用class?我需要像 A<int>
和 A
和 int
这样的东西。我需要这样的东西:
template <typename T>
class Base
{
T data;
virtual void setData(T p_data) = 0;
virtual ~Base();
template<class TC<typename TV>>
operator TC<TV>() const
{
TV tmp = (TV) data;
return TC<TV>(tmp);
}
};
template <typename T>
class A : public Base<T>
{
A(T data)
{
std::cout << data << std::endl;
}
void setData(T p_data) override
{
data = p_data;
}
};
我以前用D。在D中,下一个代码解决了这个问题(为了更好地理解我想要什么,我在下面包含了D代码):
auto opCast(K, this R)() const
{
static if (is(R ClassType : Root!T, alias Root))
K tmp = cast(K) data;
return new Root!K(tmp);
else
throw new Exception("ClassType isn't equal (T)");
}
是否有针对 C++ 的解决方案?
如果我正确阅读了你的 D 代码,那么你基本上是:
- 取正在转换的
this
对象的ClassType
,
- 对其进行模式匹配以确保它是具有 1 个参数的模板,然后提取该模板的类型,
- 将
this
对象的 data
成员转换为指定的输入类型,
- 以指定类型作为参数返回模板的新对象。
C++中没有ClassType
,所以基类class不可能获得派生对象的class类型,除非你使用CRTP 将派生类型作为模板参数传递给基础 class.
但是,您的operator
接近于接受任何类型的模板类型进行转换,您的语法有点错误。试试这样的东西:
template <typename T>
class Base
{
public:
T data;
...
template<template<typename> typename TC, typename TV>
operator TC<TV>() const
{
TV tmp = (TV) data;
return TC<TV>(tmp);
}
};
然后像这样的东西会起作用:
A<int> d(7);
A<float> e = d;
std::cout << e.data << std::endl;
要注意的是,此 operator
将转换为 任何 模板,该模板采用 data
可以转换为的参数。如果您想将 operator
限制为仅转换为同一模板,您将需要更多类似的内容:
template <typename T, template<typename> typename Derived>
class Base
{
public:
T data;
...
template<typename TV>
operator Derived<TV>() const
{
return Derived<TV>(data);
}
};
template <typename T>
class A : public Base<T, A>
{
typedef Base<T, A> my_base;
public:
A(T p_data)
{
setData(p_data);
std::cout << my_base::data << std::endl;
}
void setData(T p_data) override
{
my_base::data = p_data;
}
};
在我的代码中,我有一个抽象 class 和 ~8 个子 classes。我想问一下,在C++中是否可以将typename
和return转换为调用class?我需要像 A<int>
和 A
和 int
这样的东西。我需要这样的东西:
template <typename T>
class Base
{
T data;
virtual void setData(T p_data) = 0;
virtual ~Base();
template<class TC<typename TV>>
operator TC<TV>() const
{
TV tmp = (TV) data;
return TC<TV>(tmp);
}
};
template <typename T>
class A : public Base<T>
{
A(T data)
{
std::cout << data << std::endl;
}
void setData(T p_data) override
{
data = p_data;
}
};
我以前用D。在D中,下一个代码解决了这个问题(为了更好地理解我想要什么,我在下面包含了D代码):
auto opCast(K, this R)() const
{
static if (is(R ClassType : Root!T, alias Root))
K tmp = cast(K) data;
return new Root!K(tmp);
else
throw new Exception("ClassType isn't equal (T)");
}
是否有针对 C++ 的解决方案?
如果我正确阅读了你的 D 代码,那么你基本上是:
- 取正在转换的
this
对象的ClassType
, - 对其进行模式匹配以确保它是具有 1 个参数的模板,然后提取该模板的类型,
- 将
this
对象的data
成员转换为指定的输入类型, - 以指定类型作为参数返回模板的新对象。
C++中没有ClassType
,所以基类class不可能获得派生对象的class类型,除非你使用CRTP 将派生类型作为模板参数传递给基础 class.
但是,您的operator
接近于接受任何类型的模板类型进行转换,您的语法有点错误。试试这样的东西:
template <typename T>
class Base
{
public:
T data;
...
template<template<typename> typename TC, typename TV>
operator TC<TV>() const
{
TV tmp = (TV) data;
return TC<TV>(tmp);
}
};
然后像这样的东西会起作用:
A<int> d(7);
A<float> e = d;
std::cout << e.data << std::endl;
要注意的是,此 operator
将转换为 任何 模板,该模板采用 data
可以转换为的参数。如果您想将 operator
限制为仅转换为同一模板,您将需要更多类似的内容:
template <typename T, template<typename> typename Derived>
class Base
{
public:
T data;
...
template<typename TV>
operator Derived<TV>() const
{
return Derived<TV>(data);
}
};
template <typename T>
class A : public Base<T, A>
{
typedef Base<T, A> my_base;
public:
A(T p_data)
{
setData(p_data);
std::cout << my_base::data << std::endl;
}
void setData(T p_data) override
{
my_base::data = p_data;
}
};