C++ 三参数函数模板混淆示例 #包括 //任何类型的最大值为两个: 样板 T最大值(T a,T b) { std::cout

C++ 三参数函数模板混淆示例 #包括 //任何类型的最大值为两个: 样板 T最大值(T a,T b) { std::cout,c++,stl,C++,Stl,提出的问题是不会调用非模板重载 max(ta,tb,tc)知道max(ta,tb)但不知道有整数重载,因为它是在整数重载之后声明的。提出的问题是不会调用非模板重载 max(ta,tb,tc)知道max(ta,tb)但不知道有一个整数重载,因为它是在它后面声明的。解决方案是:为T=int专门化max,而不是定义int(int,int)函数: #include <iostream> // maximum of two values of any type: template<ty

提出的问题是不会调用非模板重载


max(ta,tb,tc)
知道
max(ta,tb)
但不知道有整数重载,因为它是在整数重载之后声明的。

提出的问题是不会调用非模板重载


max(ta,tb,tc)
知道
max(ta,tb)
但不知道有一个整数重载,因为它是在它后面声明的。

解决方案是:为
T=int
专门化
max
,而不是定义
int(int,int)
函数:

#include <iostream>

// maximum of two values of any type:
template<typename T>
T max (T a, T b)
{
    std::cout << "max<T>() \n";
    return b < a ? a : b;
}

// maximum of three values of any type:
template<typename T>
T max (T a, T b, T c)
{
    return max (max(a,b), c); // uses the template version even for ints
} //because the following declaration comes
// too late:

// maximum of two int values:
int max (int a, int b)
{
    std::cout << "max(int,int) \n";
    return b < a ? a : b;
}

int main()
{
    ::max(47,11,33); // OOPS: uses max<T>() instead of max(int,int)
}

但这是脆弱的,如果非模板函数在定义了
max
之后和专门化
max
之前使用
max
,则根据程序将是格式错误的,无需诊断


如果这是一个您无法承担的风险,那么您可以使用一些工具。SFINAE就是其中之一,它可以禁止使用
T=int
调用常规
max
。这将导致工作程序或编译错误。

解决方案是:为
T=int
专门化
max
,而不是定义e> int(int,int)函数:

#include <iostream>

// maximum of two values of any type:
template<typename T>
T max (T a, T b)
{
    std::cout << "max<T>() \n";
    return b < a ? a : b;
}

// maximum of three values of any type:
template<typename T>
T max (T a, T b, T c)
{
    return max (max(a,b), c); // uses the template version even for ints
} //because the following declaration comes
// too late:

// maximum of two int values:
int max (int a, int b)
{
    std::cout << "max(int,int) \n";
    return b < a ? a : b;
}

int main()
{
    ::max(47,11,33); // OOPS: uses max<T>() instead of max(int,int)
}

但这是脆弱的,如果非模板函数在定义了
max
之后和专门化
max
之前使用
max
,则根据程序将是格式错误的,无需诊断

如果这是一个您无法承担的风险,那么您可以使用一些工具。SFINAE就是其中之一,可能会禁止使用
T=int
调用常规
max
。这将导致工作程序或编译错误。

::max(47,11,33);
实际上是
:max(47,11,33);

这会依次调用
::max(::max(47,11,33);
,这可能会让人吃惊

由于
int
是内置的(因此没有ADL),
max(int,int)
应该在
max(T,T,T)
被定义为允许在模板中调用该版本之前可见:

对于自定义类型,由于ADL,您的
max
函数可以在以下时间后声明:

max(int,int) 
max(int,int) 
模板
T最大值(T a,T b)
{
std::cout
:max(47,11,33);
实际上是
:max(47,11,33);

这会依次调用
::max(::max(47,11,33);
,这可能会让人吃惊

由于
int
是内置的(因此没有ADL),
max(int,int)
应该在
max(T,T,T)
被定义为允许在模板中调用该版本之前可见:

对于自定义类型,由于ADL,您的
max
函数可以在以下时间后声明:

max(int,int) 
max(int,int) 
模板
T最大值(T a,T b)
{

std::不能随意调整定义函数的顺序。例如,如果在三参数模板函数之前定义(或至少声明)
int max(int,int)
函数会发生什么?或者如果使用专门化而不是重载会发生什么?比如
template int max(int,int);
。这是对max的调用(a,b)在max(a,b,c)中,使用模板而不是非模板重载。我不理解这个问题。这个电话。@Mat谢谢,我注意到了。@user463035818是的,但答案是“你错过了阅读注释”如果你在三参数模板函数之前定义(或至少声明)
int max(int,int)
函数,会发生什么?或者如果你使用专门化而不是重载,比如
template int max(int,int)会发生什么;
。是max(a,b,c)内部对max(a,b)的调用使用了模板而不是非模板重载。我不理解这个问题。这个调用。@Mat谢谢我现在注意到了。@user463035818是的,但是答案“你错过了阅读评论”并没有完全回答这个问题。我想::max(47,11,33)根据上一条注释,应调用两个参数定义。可能“uses”被误解为“call”@Kad,但有两个参数定义;一个是模板,一个是整数。注释状态
//OOPS:使用max()而不是max(int,int)
表明他们只希望调用一个整数,但这不是两阶段查找的结果,对吗?@UKMonkey我知道,我错误地执行了3参数函数调用的第一次调用,正如预期的2参数max(int,int)。@UKMonkey:“不知道有整数重载,因为它是在它之后声明的。”更复杂的是,
struct S{};S max(S,S);max(S{,S{},S{});
会正确地调用
max(S,S)
版本,即使是在后面声明。我想::max(47,11,33)期望调用两个参数定义,这是我上一个注释中的困惑。可能“uses”被误解为“call”@Kad,但有两个参数定义;一个是模板,另一个是整型。注释状态
//OOPS:使用max()而不是max(int,int)
表明他们只希望调用一个整数,但这不是两阶段查找的结果,对吗?@UKMonkey我知道,我错误地执行了3参数函数调用的第一次调用,正如预期的2参数max(int,int)。@UKMonkey:“不知道有整数重载,因为它是在它之后声明的。”更复杂的是,
struct S{};S max(S,S);max(S{},S{},S{};
将正确调用
max(S,S)
version,即使在..之后声明也是如此。这是因为3参数版本是一个模板,所以所使用的2参数版本的实例化点在main中。但是很容易意外地在两者之间添加一个函数,从而破坏程序。@StoryTeller确实如此。它是