从方法返回变量类型
Return variant type from method
所以我有一个资源管理器,它基本上是一个void*对象的字典,它有一些描述它们类型的元数据(像字符串这样的基本元数据)。我现在有一个模板方法返回一个对象:
class ResourceManager
{
template<typename Type>
Type RetrieveResource( Text name );
};
我的问题是如何使这个方法不是一个模板方法?我对尾随返回类型做了一些研究,并使用了这种时髦的语法。这个想法是,在某些时候,我将数据作为正确的类型,并且我希望将其作为该类型返回,而不需要对最终用户进行额外的强制转换。
我正在拍摄这样的东西:
auto RetrieveResource( Text name)
{
return _dictionary[ name ]; // There's more to this, but imagine it returns varying type objects.
}
我已经考虑过实现Boost::任何类型的对象,但它有点复杂(不是我懒惰)。我试图避免最终用户的模板语法。
任何帮助都太好了。此外,我不能使用Boost库结构,如变体或任何(项目规范)。提前感谢!
我知道我在这里有点要求魔法,但我认为这就是S/O的目的:寻找魔法。如果不可能,我能理解。但如果有人有创新的解决方案,那就太棒了。
除了其他答案之外,您还可以这样做,假设每个Text
键唯一地对应于具有已知的不同Type
的资源:
class BaseText
{
// constructors that take const char *, std::string, etc.
// .. whatever else you currently have in class Text
};
template<typename Type>
class Text : public BaseText
{
// constructors that take const char *, std::string, etc.
};
将ResourceManager
改为:
class ResourceManager
{
template<typename Type>
Type RetrieveResource( Text<Type> name );
};
注意,这仍然需要编译时多态性,但这意味着只要您的用户能够获得正确类型的Text<Type>
版本,他们就可以使用它来获得正确类型的资源,而不必再次显式地提供Type
参数,因此它看起来就像一个普通的函数调用。
如果一组可能的Text<Type>
对象可以用正确的类型静态声明和初始化,这很容易工作,我不确定在您的情况下是否正确。如果,相反,用户必须能够在运行时创建它们,但是,他们需要知道要创建的正确类型,所以它只是把问题往后推了一点:然而,如果相同的Text<Type>
对象将被反复使用,这可能足够方便。
请注意,如果您或客户端需要在某种数据结构中存储不同的Text<Type>
对象,那么您也不走运,因为这将需要某种类型擦除(即上转换为BaseText
)。所以这是一个专门的解决方案,但它可能是有用的,这取决于事情是如何结构化的(我真的不能知道没有看到更多的代码)。
EDIT:根据下面的注释,对象的类型似乎是由客户端在插入对象时确定的,所以您可能会这样做:
class ResourceManager
{
BaseText PutResource( const BaseText& name, BaseResource& resource );
template<typename Type>
Text<Type> PutResource( const BaseText& name, Type& resource );
BaseResource& RetrieveResource( const BaseText& name );
template<typename Type>
Type& RetrieveResource( const Text<Type>& name );
};
因此客户端需要持有唯一类型的键对象,以便稍后检索资源;如果他们选择通过将其上转换回BaseText
来键入erase,那么他们将负责正确地恢复类型信息,要么在检索之前向下转换键,要么在检索之后向下转换资源。
请注意,这只是你必须做的事情之上的一个额外选项:如果你想使用非特定类型的键来提供对资源的访问,那么唯一的方法就是返回一个非特定的资源类型(即BaseResource
, boost::any
, boost::variant<...>
,或它们的道德等价之一)。然而,创建BaseText
的特定类型子类允许您使用完全相同的语法(即不需要显式模板参数)获得正确类型的资源。此外,这允许以下用法:
// tree is a resource of type `Tree`
auto key = manager.PutResource("Tree01", tree);
// ...
const BaseText& basekey = key; // lose type information
// ...
// these are all equivalent
Tree& tree = dynamic_cast<Tree&>(manager.RetrieveResource("Tree01"));
Tree& tree = dynamic_cast<Tree&>(manager.RetrieveResource(basekey));
Tree& tree = manager.RetrieveResource(key); // no casts required
Tree& tree = manager.RetrieveResource<Tree>("Tree01")
dynamic_cast
版本基本上是你需要做的,没有这些模板重载,但其他两个版本是额外的选项,你可以使用这种方法而不需要任何运行时成本。
恐怕那样会太暧昧了。不能通过返回类型重载,也不能使用auto
作为返回类型
我认为,最好的选择将是返回一些基类指针。缺点是你强迫任何人从它派生,但是基类的智能架构可以有更多的优点
- 从模板创建通用打印函数,以打印基元数据类型变量的值
- 指针数据类型变量如何包含对象?
- 将 static_cast<int>(-15) 分配给静态常量字符类型变量
- 将内置类型变量传递给只有一个类类型参数的"+"运算符函数时自动类型转换的构造函数
- 如何为结构类型变量赋值
- 如何将字符类型变量附加到字符串中?
- 共享或私有 openmp 代码中的结构化类型变量
- 有没有办法在 c++ 中制作类型变量?
- 从其他类声明类类型变量会给出 C2143 错误(在"*"之前缺少";")
- 如何检查类中定义的枚举类型变量是否被分配给?
- 将子类实例保存在父类型变量中并通过父变量使用 Child 函数?
- 是否可以在没有结构的情况下创建新的类型变量?
- 为什么类型变量;不调用默认 CTR
- 如何使用CIN将输入整数值获取到char类型变量中
- 如何为 char** 类型变量提供适当的值,以便将其分配给字符串变量
- 在C++标准中哪里说必须初始化 const 内置类型变量的定义
- 为什么可以将其他类型变量用作C 中常量参考参数参数的参数
- Eclipse CDT 打开声明的自动类型变量
- 如何计算长长类型变量中的位数
- 将自动类型变量初始化为零.这种类型安全吗?