如何使用std :: max()带有两种不同类型的参数?

问题描述 投票:0回答:3

使用C ++编译器在

std::max()
函数中使用两种不同的数字变量类型时会出现错误? (例如
int
long
)。 我的意思是:

“有时我们在两种不同的数字变量类型中使用

std::max()函数时会遇到这个问题,因此编译器会出现错误以防止此问题”。

	
编译器会产生错误,因为它无法为

std::max
c++ compiler-errors max function-templates
3个回答
6
投票
如果您通过明确提供模板参数来解决扣除歧义,那么您将能够将不同的类型使用为

std::max

参数
std::max

为什么在 @bolov的答案中描述了使用公共类型作为其参数(而不是使用两个独立类型)的原因:该函数实际上希望将

reference

返回最大值。
    

std::max(1, 2.0); // Error
std::max<double>(1, 2.0); // OK

返回具有最大值的参数的引用。这样的主要原因是因为它是一个通用功能,因此可以与昂贵的复制类型一起使用。另外,您实际上可能只需要引用对象的副本。

由于它返回对参数的引用,因此所有参数都必须为同一类型。
    
直接答案是因为

std::max

3
投票
std::max

仅采用一个定义两个参数类型的模板参数。如果/当您尝试通过不同类型的参数时,编译器无法决定将这两种用于模板参数中的哪种类型,因此代码模棱两可。如C ++ 98中最初定义的那样,

std::min

std::max

具有类似的签名(C ++ 03,§[lib.alg.min.max]):


2
投票
因此,这里的基本思想是该函数通过引用接收两个对象,并返回对其中一个对象的引用。如果它收到了两种不同类型的对象,它将无法返回对输入对象的引用,因为其中一个对象必然与返回的对象不同(因此,@bolov对此部分是正确的,但是我认为这真的不是整个故事)。

具有现代编译器/标准库,如果您不能处理值而不是参考,则可以轻松地在此通用顺序上编写代码:

std::max
使您很容易处理您的传递
template<class T> const T& min(const T& a, const T& b);

template<class T, class Compare>
const T& min(const T& a, const T& b, Compare comp);

template<class T> const T& max(const T& a, const T& b);

template<class T, class Compare>
const T& max(const T& a, const T& b, Compare comp);
template <class T, class U>
std::common_type<T, U> min(T const &a, U const &b) { 
    return b < a ? b : a;
}

template <class T, class U>
std::common_type<T, U> max(T const &a, U const &b) { 
    return a < b ? b : a;
}
(或其他类型的其他类型,只要

int
可以推断出某种常见类型,并且为它们定义了一些常见的类型两种类型的对象。

,但在1998年,即使

long

std::common_type

可用,因此很容易做到,该解决方案可能不会被接受(正如我们将看到的那样,这仍然是一个疑问,这是否是一个好主意) - 在时间的时候,许多人仍在思考很多继承方面,因此(或多或少)是理所当然的,您经常在这两个参数确实是某种派生类型的情况下经常使用它通用订单:
a<b

在这种情况下,上面返回值而不是返回参考的版本会导致严重的问题。 
std::common_type
将是
class Base { // ... virtual bool operator<(Base const &other); }; class Derived1 : public Base { // ... }; class Derived2 : public Base { // ... }; Derived1 d1; Derived2 d2; Base &b = std::max(d1, d2);
,所以我们最终将参数切成薄片以创建一个类型的对象,然后返回。这很少会提供理想的行为(在某些情况下,例如
common_type<Derived1, Derived2>
是抽象的基类,甚至不会编译)。

可能值得注意的是另一点:即使在看似简单的情况下应用,也可以产生您可能不会期望的结果。例如,让我们考虑调用上面定义的模板:

Base

给我们留下一个明显的问题:哪种类型将是?

即使我们已经将其传递给

Base

和一个
Base
,但结果的类型既不是(至少可能)
std::common_type
auto x = min(-1, 1u);
(例如,很可能是
x

)!

    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.