如何使用另一个具有显式特化的模板参数推断模板 return 类型?
How to deduce template return type with another template parameter with explicit specialization?
我有一个具有以下签名的(成员)函数:
template<Type TypeToAllocate, typename Str>
Str* allocate();
Type
是一个枚举,根据提供的枚举,我想 return 类型为 Str
的不同指针。
现在我不确定我该怎么做。示例代码在这里:
#include <functional>
#include <vector>
enum class Type {
A,
B
};
struct Bar{};
struct Baz{};
struct Foo {
Type t;
union {
Bar b;
Baz bz;
};
};
struct Util {
std::vector<Foo> foos;
template<Type TypeToAllocate, typename Str>
Str* allocate();
};
template<>
Bar* Util::allocate<Type::A>() {
Foo& f = foos.emplace_back(Foo{});
f.t = Type::A;
f.b = Bar{};
return &f.b;
}
int main() {
Util u{};
Bar* b = u.allocate<Type::A>(); // this does not work
}
我不确定 Str
在您的代码中的作用。如果这只是您尝试将枚举值映射到 Bar
或 Baz
的一部分,那么我认为您不需要它。
我会使用一个特征,它可以很容易地针对 Type
:
的不同值进行专门化
enum class Type {
A,
B
};
struct Bar{};
struct Baz{};
template <Type t> struct TypeMapper;
template <> struct TypeMapper<Type::A> { using type = Bar; };
template <> struct TypeMapper<Type::B> { using type = Baz; };
template <Type t> using TypeMapper_t = TypeMapper<t>::type;
struct Util {
template<Type t>
TypeMapper_t<t>* allocate() {
return new TypeMapper_t<t>();
}
};
int main() {
Util u{};
Bar* b = u.allocate<Type::A>();
}
我还建议您使用 std::variant<Bar,Baz>
而不是 union。
我有一个具有以下签名的(成员)函数:
template<Type TypeToAllocate, typename Str>
Str* allocate();
Type
是一个枚举,根据提供的枚举,我想 return 类型为 Str
的不同指针。
现在我不确定我该怎么做。示例代码在这里:
#include <functional>
#include <vector>
enum class Type {
A,
B
};
struct Bar{};
struct Baz{};
struct Foo {
Type t;
union {
Bar b;
Baz bz;
};
};
struct Util {
std::vector<Foo> foos;
template<Type TypeToAllocate, typename Str>
Str* allocate();
};
template<>
Bar* Util::allocate<Type::A>() {
Foo& f = foos.emplace_back(Foo{});
f.t = Type::A;
f.b = Bar{};
return &f.b;
}
int main() {
Util u{};
Bar* b = u.allocate<Type::A>(); // this does not work
}
我不确定 Str
在您的代码中的作用。如果这只是您尝试将枚举值映射到 Bar
或 Baz
的一部分,那么我认为您不需要它。
我会使用一个特征,它可以很容易地针对 Type
:
enum class Type {
A,
B
};
struct Bar{};
struct Baz{};
template <Type t> struct TypeMapper;
template <> struct TypeMapper<Type::A> { using type = Bar; };
template <> struct TypeMapper<Type::B> { using type = Baz; };
template <Type t> using TypeMapper_t = TypeMapper<t>::type;
struct Util {
template<Type t>
TypeMapper_t<t>* allocate() {
return new TypeMapper_t<t>();
}
};
int main() {
Util u{};
Bar* b = u.allocate<Type::A>();
}
我还建议您使用 std::variant<Bar,Baz>
而不是 union。