有没有办法将函数的 return 类型指定为模板参数
Is there a way to specify a function's return type as a template parameter
我正在编写一个函数模板,它处理很多 N
类型的对象(只能是几个不同的东西,但是这个模板中有很多逻辑我不想在单独的函数中复制)。在这个函数的几个地方,我也有像 auto somevar = SomeFunction(someobject);
这样的声明,其中 someobject
是类型 N
并且 SomeFunction
被重载,根据 [= 的类型返回不同的类型13=] — 但重要的是,没有 SomeFunction
returns 和 N
的超载。现在,我想要一个容器(具体来说,std::unordered_set
),而不是普通变量,其元素属于 SomeFunction
返回的类型,但我无法弄清楚如何编写必要的class 模板参数。
我已经尝试 std::unordered_set<auto>
希望编译器可以从它初始化的元素中推断出类型,但这没有用。我尝试了 std::unordered_set<SomeFunction(someobject)>
、std::unordered_set<SomeFunction(someobject)::type>
和 std::unordered_set<typeof(SomeFunction(someobject))>
,但这些都不起作用。似乎 C++ 标准缺少一种直接表达这一点的方法。
我所做的是编写一个 class 模板 some_transform
可以像这样使用 std::unordered_set<some_transform<N>::Type>
,其中 some_transform
本质上映射给定类型 N
到 SomeFunction
的相应 return 值。实际映射是在模板 class some_transform
的特化中定义的,所以它看起来像这样:
template <typename N> class some_transform
{
public:
typedef N Type; // this identity mapping is not useful, except so the IDE expects a member type by this name
};
template <> class some_transform<A>
{
public:
typedef X Type;
};
template <> class some_transform<B>
{
public:
typedef Y Type;
};
使用此 class 模板,some_transform<A>::Type
解析为类型 X
,some_transform<B>::Type
解析为类型 Y
。因此表达式 some_transform<N>::Type
可以用在需要类型的模板参数中,在带有参数 N
的模板中,实际类型参数(X
或 Y
)取决于关于 N
是 A
还是 B
。我只需要确保这个 class 正确地将给 SomeFunction
的类型(如问题中提到的)映射到由 SomeFunction
编辑的相应类型 return。
请注意,标识符 Type
并不特殊,可以是任何东西;事实上,some_transform<N>
class 可以有多个成员类型,e。 g. IndexType
和 HashType
;并且 class 的名称可能更好,如 TypeMap
,其中成员类型的名称指示完成的转换或映射。
正如其他人所说,您应该使用 decltype
。所以你会写 std::unordered_set<decltype(SomeFunction(someobject))>
作为你的 return 类型。
旁注:您可能会在网上找到 GCC 编译器在 C++11 添加 decltype
之前添加支持的 typeof
。 typeof
的工作方式与 decltype
相同,但不是 C++ 标准的一部分,因此 non-GCC 编译器不支持。因此,您应该始终使用 decltype
而不是 typeof
.
我正在编写一个函数模板,它处理很多 N
类型的对象(只能是几个不同的东西,但是这个模板中有很多逻辑我不想在单独的函数中复制)。在这个函数的几个地方,我也有像 auto somevar = SomeFunction(someobject);
这样的声明,其中 someobject
是类型 N
并且 SomeFunction
被重载,根据 [= 的类型返回不同的类型13=] — 但重要的是,没有 SomeFunction
returns 和 N
的超载。现在,我想要一个容器(具体来说,std::unordered_set
),而不是普通变量,其元素属于 SomeFunction
返回的类型,但我无法弄清楚如何编写必要的class 模板参数。
我已经尝试 std::unordered_set<auto>
希望编译器可以从它初始化的元素中推断出类型,但这没有用。我尝试了 std::unordered_set<SomeFunction(someobject)>
、std::unordered_set<SomeFunction(someobject)::type>
和 std::unordered_set<typeof(SomeFunction(someobject))>
,但这些都不起作用。似乎 C++ 标准缺少一种直接表达这一点的方法。
我所做的是编写一个 class 模板 some_transform
可以像这样使用 std::unordered_set<some_transform<N>::Type>
,其中 some_transform
本质上映射给定类型 N
到 SomeFunction
的相应 return 值。实际映射是在模板 class some_transform
的特化中定义的,所以它看起来像这样:
template <typename N> class some_transform
{
public:
typedef N Type; // this identity mapping is not useful, except so the IDE expects a member type by this name
};
template <> class some_transform<A>
{
public:
typedef X Type;
};
template <> class some_transform<B>
{
public:
typedef Y Type;
};
使用此 class 模板,some_transform<A>::Type
解析为类型 X
,some_transform<B>::Type
解析为类型 Y
。因此表达式 some_transform<N>::Type
可以用在需要类型的模板参数中,在带有参数 N
的模板中,实际类型参数(X
或 Y
)取决于关于 N
是 A
还是 B
。我只需要确保这个 class 正确地将给 SomeFunction
的类型(如问题中提到的)映射到由 SomeFunction
编辑的相应类型 return。
请注意,标识符 Type
并不特殊,可以是任何东西;事实上,some_transform<N>
class 可以有多个成员类型,e。 g. IndexType
和 HashType
;并且 class 的名称可能更好,如 TypeMap
,其中成员类型的名称指示完成的转换或映射。
正如其他人所说,您应该使用 decltype
。所以你会写 std::unordered_set<decltype(SomeFunction(someobject))>
作为你的 return 类型。
旁注:您可能会在网上找到 GCC 编译器在 C++11 添加 decltype
之前添加支持的 typeof
。 typeof
的工作方式与 decltype
相同,但不是 C++ 标准的一部分,因此 non-GCC 编译器不支持。因此,您应该始终使用 decltype
而不是 typeof
.