提问人:glades 提问时间:4/13/2022 更新时间:4/14/2022 访问量:276
从基对象获取派生类的模板参数
Get template parameter of derived class from base object
问:
总之:
- 我有一个没有模板参数的基类和一个有两个参数的派生类。
A_base
A
- 该函数仅接受基类对象
foo()
foo()
应该返回一个对象,该对象与派生类的第一个模板参数 T 具有相同的类型。
这样做的原因是我不想将 foo() 专门用于 A 的所有变体,您可以想象这可能是数百个。
为了在代码中说明这一点,请执行以下操作:
#include <cstdlib>
struct A_base
{
};
template <typename T, size_t S>
struct A : A_base
{
using P = T; // <-- how do I get here from base class A?
T arr[S];
};
template <typename T>
auto foo(const A_base& ref) -> decltype(/* somehow get P*/)
{
return /* object of type P */;
}
int main()
{
A<int, 10> a;
foo(a);
}
我将另一个参数 P 键入为 T,因为我认为这将使类“拥有”该类型并提供更好的访问。我希望有一个没有虚拟方法的解决方案,因为直到现在我都在使用虚拟通话。
答:
0赞
Michaël Roy
4/13/2022
#1
编译器需要在编译时知道 foo() 的返回类型。如果你不能A_base做一个模板,为什么不把foo()本身做一个函数模板呢?
如:
#include <type_traits>
struct A_base{};
template <typename T>
struct B : A_base
{
static constexpr T val{};
};
template<typename T>
auto foo(const T&)
{
static_assert(std::is_base_of_v<A_base, T>); // this works without
// depending on a particular
// constructor
return T::val; // for example.
}
struct C {};
int main()
{
auto x = foo(B<int>{});
return std::is_same_v<int, decltype(x)>;
}
评论
0赞
glades
4/13/2022
谢谢,但是如果我想自动推断它怎么办?
0赞
Michaël Roy
4/14/2022
@glades 什么意思?在处理模板时,通常的规则始终适用:在编译时必须知道类型。否则,请使用虚拟函数。
0赞
glades
4/14/2022
#2
很抱歉回答我自己的问题,但我发现了一种可能性。我只是创建一个中间虚拟类,其中只有一个继承自 的模板参数 T。然后,我可以使用这个中间类,而不是 参数的基类:A_middle
A
foo()
#include <cstdlib>
struct A_base {};
template <typename T>
struct A_middle : A_base { };
template <typename T, size_t S>
struct A : A_middle<T>
{
T arr[S];
};
template <typename T>
T foo(const A_middle<T>& ref) // deduction works as expected
{
T var;
return var;
}
int main()
{
A<int, 10> b;
foo(b);
}
评论
T
foo
const T& ref
dynamic_cast