C++ 模板函数可切换返回类型

C++ Template function chagneable return type

提问人:josephroy 提问时间:3/12/2023 更新时间:3/12/2023 访问量:95

问:

我有模板结构

template <class T>
struct Vector2
{
    T x, y;
};

使用以下函数重载 + 运算符

template <typename T1, typename T2>
Vector2 operator+(const Vector2<T1>& v1, const Vector2<T2>& v2) 
{
    auto x = v1.x + v2.x;
    auto y = v1.y + v2.y;
    Vector2 result{ x, y };
    return result;
}

我收到错误,我理解为什么返回类型没有为模板提供类型。我的问题是我希望返回类型发生变化。如果两个参数都是 Vector2,则返回类型应为 Vector2。但是,如果其中一个参数是 Vector2,则返回类型应提升为 Vector2。argument list for class template "Vector2" is missing

我尝试使用 auto,以便在创建变量结果时,它会正确转换,并且 Vector2 不需要模板参数。我知道这应该像

Vector2 vectorInt = { 3, 2 };

Vector2 vectorDouble = { 1.4,4.4 };

两者都可以正常工作。主要问题是函数本身的返回类型。

我知道我可能做得不对,因为我目前是学习C++的新手,从我的其他语言知识中学习。

我想知道的是,这是否可能,如果可能,如何?

C++ 函数 模板 重载 operator-keyword

评论

0赞 Ch3steR 3/12/2023
如果两个参数都是 Vector2,则返回类型应为 Vector2 - is a template is a type。我尝试使用 auto,以便在创建变量结果时,它会正确转换,并且 Vector2 不需要模板参数。我没有看到自动,我猜你的意思是CTAD?Vector2Vector2<T>
0赞 josephroy 3/12/2023
@Ch3steR 是的,我知道我提供的代码有效以及为什么。返回类型需要是 Vector2<something>但我需要确定 <something> 是什么。auto 在函数定义中用作 x 和 y。
0赞 Ch3steR 3/12/2023
输入的类型是吗?somethingVector<something>T1 + T2

答:

0赞 Red.Wave 3/12/2023 #1
> Vector2 vectorInt = { 3, 2 };
> Vector2 vectorDouble = { 1.4,4.4 };

此结构使用 CTAD。编译器根据提供的初始值设定项类型确定模板参数。

但是编译器无法从函数声明或定义中找出模板参数。您可以改用返回类型:auto

template <typename T1, typename T2>
auto operator+(const Vector2<T1>& v1, const Vector2<T2>& v2) 
{
    auto x = v1.x + v2.x;
    auto y = v1.y + v2.y;
    return Vector2{ x, y };
};

但是,如果要检查约束模板中的返回类型,这可能还不够。因此,您可以通过尾随返回类型来更详细:

template <typename T1, typename T2>
auto operator+(const Vector2<T1>& v1, const Vector2<T2>& v2)
    -> Vector2<decltype(v1.x + v2.x)>
{
    auto x = v1.x + v2.x;
    auto y = v1.y + v2.y;
    return { x, y };
};

或者使用旧样式的返回类型:

template <typename T1, typename T2>
Vector2<decltype(std::declval<T1>() + std::declval<T2>())>
operator+(const Vector2<T1>& v1, const Vector2<T2>& v2)
{
    auto x = v1.x + v2.x;
    auto y = v1.y + v2.y;
    return { x, y };
};

在上面的代码片段中,您也可以将表达式替换为。但我更喜欢这个版本的准确性。decltype(...)std::common_type_t<T1,T2>decltype