返回具有模板功能的通用类型
returning a generic type with template functions
我是使用模板的新手,我想制作一个返回通用类型的函数。我制作了一个非常简单的模板
enum tag { SHORT, INT, FLOAT, DOUBLE };
template <typename T>
T get_val(tag t){
switch (t) {
case SHORT: return .. //returns a short;
case INT: return .. //returns a int;
case FLOAT: return .. //returns a float;
case DOUBLE: return .. //returns a double;
}
}
问题在于,浮子和双打作为整数编号返回。所以我想知道为什么会发生这种情况,如果有一种方法可以正确使用。
您不得使用类似的 switch
语句使用其他返回类型。
但是,如果在编译时已知get_val
的输入,则可以使用模板元编程技术来获取所需的东西。
enum tag { SHORT, INT, FLOAT, DOUBLE };
template <tag t> struct return_type_chooser;
template <> struct return_type_chooser<SHORT>
{
using type = short;
};
template <> struct return_type_chooser<INT>
{
using type = int;
};
template <> struct return_type_chooser<FLOAT>
{
using type = float;
};
template <> struct return_type_chooser<DOUBLE>
{
using type = double;
};
template <tag t>
typename return_type_chooser<T>::type get_val()
{
...
}
您可以使用:
get_val<SHORT>()
但不是
get_val(SHORT)
更新,响应OP的评论
如果仅在运行时知道get_val
的输入,则std::any
(C 17)或boost::any
应作为返回类型工作。
我建议使用有限类型的有限子集中的类型进行变体和运行时检查:
:使用一个公共接口进行正确类型的枚举的变体(这是一个天真的版本,您应该真正使用std::variant
和get_if
):
enum variant_type
{
variant_null,
variant_int,
variant_float,
variant_double,
}
class variant
{
public:
// Add constructors with the correct type for the
// underlying storage
variant() = default;
variant(int x);
variant(float x);
variant(double x);
// ensure you can check for empty variants and check the type
explicit operator int() const;
explicit operator float() const;
explicit operator double() const;
explicit operator bool() const;
variant_type type() const;
private:
variant_type type_ = variant_null;
void* data_ = nullptr;
};
然后,添加许多自定义功能或方法过载,使您可以在运行时选择正确的方法:
class my_handler
{
public:
my_handler(const variant& v)
{
switch (v.type()) {
case variant_null;
open(nullptr); break;
case variant_int;
open(int(v)); break;
case variant_float;
open(float(v)); break;
case variant_double;
open(double(v)); break;
}
}
private:
void open(std::nullptr_t nullp);
void open(int x);
void open(float x);
void open(double x);
};
这使您可以拥有一个对有限类型子集的通用的公共接口,但是您可以避免在编译时知道正确的类型。
可以使用std::variant
和get_if
更惯用地完成这一切,而不是编写自己的自定义变体类。我只是作为一个(例如Windows API和QT)实现了多少库(例如Windows API和QT)的(效率低下的)示例。
相关文章:
- 错误:在尝试检测 std::cout 是否<< t 时,功能强制转换为数组类型;有效
- 对于非常量指针类型的参数,未调用具有常量指针模板类型参数的功能
- C++从成员类型中扣除类型的功能模板?
- 这种错误的原因是什么:将"功能"重新定义为不同类型的符号
- 模板功能:根据类型名称进行转换
- 如何在同一个模板功能上专门化几种类型?
- 错误:未知类型名称"功能跟踪"
- 我对C 中共享指针列表进行排序的功能未完成类型
- 共享_ptr中多功能数组的类型是什么
- 确定功能主体中的返回类型
- 返回类型不可知模板类成员功能
- 类型推论模板功能返回类型
- C 功能模板指定第二个模板参数类型
- 为什么指定数据类型而不是构造功能参数?C
- C 尝试使用模板输出功能来显示不同类型的数据
- 为什么BOOST :: HANA :: EXAREMIS ::键入实验功能?类型列表的棘手是什么
- 将多种类型传递给STD ::功能C
- C 中此功能的返回类型的含义
- C++ 使用包含不同类型功能对象的基和派生类的 Reactor
- 请求从非标量类型转换为非标量类型(功能)