gpt4 book ai didi

c++ - 在函数模板中将一个类型名称映射到另一个类型名称

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:07:56 25 4
gpt4 key购买 nike

我正在编写函数模板来处理 float , double , std::complex<float> , 和 std::complex<double>类型。

我经常需要声明一个对应于“相同精度但纯实数”的类型。所以两者都是floatstd::complex<float>将映射到 float

我一直在用这样的重载来做这件事:

template <typename numeric_t, typename real_t>
numeric_t foo(numeric_t x) {
real_t y = abs(x);
return x/y;
}

template <typename T> // Used when x is real
T bar(T x) { return foo<T,T>(x); }

template <typename T> // Overload takes precedence when x is complex
complex<T> bar(complex<T> x) { return foo<complex<T>,T>(x); }

但这看起来很麻烦,特别是因为我需要为我编写的每个此类函数定义这些。有更好的方法吗?


在这个例子中,我可以这样做:

template <typename numeric_t>
numeric_t bar(numeric_t x) {
auto y = abs(x);
return x/y;
}

因为abs()已适当重载。那太好了!这正是我要找的。但是,如果我不调用 abs 怎么办? ?或者如果 real_t是返回类型吗?

最佳答案

如果你定义一个简单的类型特征来检测正确的返回类型,像下面的 realType

template <typename T>
struct realType
{ using type = T; };

template <typename T>
struct realType<std::complex<T>>
{ using type = T; };

bar() 函数可以写成

template <typename T>
T bar (T const & x)
{ return foo<T, typename realType<T>::type>(x); }

下面是一个完整的编译示例

#include <complex>

template <typename T>
struct realType
{ using type = T; };

template <typename T>
struct realType<std::complex<T>>
{ using type = T; };

template <typename numeric_t, typename real_t>
numeric_t foo(numeric_t x)
{
real_t y = abs(x);
return x/y;
}

template <typename T>
T bar (T const & x)
{ return foo<T, typename realType<T>::type>(x); }

int main ()
{
using type1 = decltype(bar<float>(1.0f));
using type2 = decltype(bar<std::complex<double>>(1.0));

static_assert(std::is_same<type1, float>{}, "!");
static_assert(std::is_same<type2, std::complex<double>>{}, "!");
}

题外话建议。

您的 foo() 函数有两种模板类型,但只能从输入参数 (x) 推导出第一种 (numeric_t) ).所以你不得不明确他们两个。

如果你颠倒模板类型的顺序

template <typename real_t, typename numeric_t>
numeric_t foo(numeric_t x)
{
real_t y = abs(x);
return x/y;
}

你可以调用 foo() 只解释第一个,让编译器推导出第二个;所以 bar() 可以写成

template <typename T>
T bar (T const & x)
{ return foo<typename realType<T>::type>(x); }

-- 编辑 --

根据 aschepler 的建议(谢谢!),您可以从 numeric_t 中推断出 foo() 中的 real_t 类型;所以,不用切换这两种模板类型,你可以这样写foo()

template <typename numeric_t,
typename real_t = typename realType<numeric_t>::type>
numeric_t foo(numeric_t x)
{
real_t y = abs(x);
return x/y;
}

bar()简单地变成了

template <typename T>
T bar (T const & x)
{ return foo(x); }

关于c++ - 在函数模板中将一个类型名称映射到另一个类型名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46699376/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com