【问题标题】:How to promote two template types for arithmitic operations like builtin types do?如何像内置类型一样为算术运算提升两种模板类型?
【发布时间】:2016-01-24 05:29:15
【问题描述】:

如果我有一个通用结构/类:

template<typename T>
struct Container
{
    T value;
    Container(const Value& value) : value(value) { }
};

我想对其中两个执行操作:

template<typename T, typename U>
Container<T> operator+(const Container<T>& lhs, const Container<U>& rhs)
{
    return Container<T>(lhs.value + rhs.value);
}

问题是如果lhsContainer&lt;int&gt; 类型并且rhsContainer&lt;float&gt; 类型,那么我会得到一个Container&lt;int&gt; 回来。但如果我要执行auto result = 2 + 2.0f,那么result 将属于float 类型。所以内置类型和自定义类型的行为是不一致的。

那么我将如何处理 operator+ 重载并使其返回 Container&lt;float&gt;,就像 C++ 如何使用内置类型处理算术提升一样?

【问题讨论】:

  • @PiotrSkotnicki 是的。

标签: c++ templates c++11 arithmetic-expressions type-promotion


【解决方案1】:

只要您使用两种类型的模板之一,您就有可能对总和的结果进行强制转换。例如,如果您不小心选择了int 作为目标类型,即使总和结果为float,它也会被强制转换为所选类型。

无论如何,从 C++11 开始,您可以像上面的示例一样依赖 decltype 说明符(或者至少,如果 Container::TContainer::UContainer::U 的类型987654326@运算符已定义)。

我还使用了 auto 说明符作为 operator+ 的返回值,因为它从 C++14 开始可供我们使用,而且确实非常有用。

它遵循上面提到的工作示例:

#include <iostream>
#include <vector>

template<typename T>
struct Container
{
    T value;
    Container(const T& value) : value(value) { }
};

template<typename T, typename U>
auto operator+(const Container<T>& lhs, const Container<U>& rhs)
{
    return Container<decltype(lhs.value+rhs.value)>{lhs.value + rhs.value};
}

int main()
{
    Container<int> c1{1};
    Container<float> c2{0.5};
    std::cout << (c1+c2).value << std::endl;
}

【讨论】:

  • 看起来不错。您可以使用 make_container 辅助函数使其更具可读性,允许推断模板参数:return make_container(lhs.value + rhs.value);
  • decltype 中执行的操作是否增加了额外的运行时成本?如果我将结果存储在一个临时的auto 变量中并执行类似return Container&lt;decltype(result)&gt;(result); 之类的操作会更好吗?
  • decltype 在编译时以及整个类型系统中都已解决(因此被清除),因此您不会有任何额外的运行时成本。
猜你喜欢
  • 2023-01-11
  • 1970-01-01
  • 2011-04-23
  • 2011-02-24
  • 1970-01-01
  • 2020-10-11
  • 2018-01-21
  • 1970-01-01
  • 2020-05-20
相关资源
最近更新 更多