Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 过载a C++;根据返回值执行函数_C++_Function_Puzzle_Overloading - Fatal编程技术网

C++ 过载a C++;根据返回值执行函数

C++ 过载a C++;根据返回值执行函数,c++,function,puzzle,overloading,C++,Function,Puzzle,Overloading,我们都知道,可以根据以下参数重载函数: int mul(int i, int j) { return i*j; } std::string mul(char c, int n) { return std::string(n, c); } 可以根据返回值重载函数吗?定义一个函数,根据返回值的使用方式返回不同的内容: int n = mul(6, 3); // n = 18 std::string s = mul(6, 3); // s = "666" // Note that both inv

我们都知道,可以根据以下参数重载函数:

int mul(int i, int j) { return i*j; }
std::string mul(char c, int n) { return std::string(n, c); } 
可以根据返回值重载函数吗?定义一个函数,根据返回值的使用方式返回不同的内容:

int n = mul(6, 3); // n = 18
std::string s = mul(6, 3); // s = "666"
// Note that both invocations take the exact same parameters (same types)

您可以假设第一个参数在0-9之间,无需验证输入或进行任何错误处理。

据我所知,您不能(非常遗憾……)。作为一种解决方法,您可以定义一个“out”参数,并重载该参数。

您不能通过返回值重载,因为调用方可以对其执行任何操作(或不执行任何操作)。考虑:

mul(1,2)


返回值刚刚被丢弃,因此它无法仅根据返回值选择重载。

您可以使用模板,但在调用时必须指定模板参数。

是否将其放在其他命名空间中?我会这样做的。严格来说,它不是一个重载,而是一个只包含两个名称相同但作用域不同的方法(因此使用::scope解析运算符)


所以stringnamespace::mul和intnamespace::mul。也许这并不是你真正想要的,但这似乎是唯一的方法。

你不能仅仅基于返回值来重载函数


但是,严格来说,这不是一个重载函数,可以从函数返回一个重载转换运算符的类的实例。

< P>不在C++中。在上面的示例中,您将得到返回值,它是一个int,转换成
string
可以理解的内容,很可能是
char
。这将是ASCII 18或“设备控制2”。

您可以执行以下操作

template<typename T>
T mul(int i,int j){
    return i * j;
}

template<>
std::string mul(int i,int j){
    return std::string(j,i);
}
模板
T mul(int i,int j){
返回i*j;
}
模板
std::string mul(inti,intj){
返回std::字符串(j,i);
}
然后这样称呼它:

int x = mul<int>(2,3);
std::string s = mul<std::string>(2,3);
intx=mul(2,3);
std::string s=mul(2,3);

无法重载返回值。

在中间类中使用隐式转换

class BadIdea
{
  public:
    operator string() { return "silly"; }
    operator int() { return 15; }
};

BadIdea mul(int, int)

你明白了,但这个想法很糟糕。

我想你可以让它返回一些奇怪的类型Foo,只捕获参数,然后Foo有一个隐式运算符int和运算符字符串,它会“工作”,尽管它不会真的过载,而是隐式转换技巧

class mul
{
public:
    mul(int p1, int p2)
    {
        param1 = p1;
        param2 = p2;
    }
    operator int ()
    {
        return param1 * param2;
    }

    operator std::string ()
    {
        return std::string(param2, param1 + '0');
    }

private:
    int param1;
    int param2;
};

并不是说我会使用它。

让mul是一个类,mul(x,y)是它的构造函数,并重载一些强制转换操作符。

您可以使用上面的函子解决方案。C++不支持除了const之外的函数。可以基于常量重载

您必须告诉编译器使用哪个版本。在C++中,你可以用三种方法来做。 通过键入 您有点作弊,因为您向等待字符的函数发送了一个整数,并且在“6”的字符值不是6而是54(ASCII)时错误地发送了数字6:

当然,正确的解决办法是

std::string s = mul(static_cast<char>(54), 3); // s = "666"
可与以下代码一起使用:

int n = mul((int *) NULL, 6, 3); // n = 18
std::string s = mul((std::string *) NULL, 54, 3); // s = "666"
通过模板化返回值显式区分调用 使用此解决方案,我们创建了一个“虚拟”函数,其代码在实例化时不会编译:

template<typename T>
T mul(int i, int j)
{
   // If you get a compile error, it's because you did not use
   // one of the authorized template specializations
   const int k = 25 ; k = 36 ;
}
模板
T mul(int i,int j)
{
//如果出现编译错误,那是因为没有使用
//授权的模板专门化之一
常数int k=25;k=36;
}
您会注意到此函数不会编译,这是一件好事,因为我们只希望通过模板专门化使用一些有限的函数:

template<>
int mul<int>(int i, int j)
{
   return i * j ;
}

template<>
std::string mul<std::string>(int i, int j)
{
   return std::string(j, static_cast<char>(i)) ;
}
模板
int mul(int i,int j)
{
返回i*j;
}
模板
std::string mul(inti,intj)
{
返回std::string(j,static_cast(i));
}
因此,将编译以下代码:

int n = mul<int>(6, 3); // n = 18
std::string s = mul<std::string>(54, 3); // s = "666"
int n=mul(6,3);//n=18
std::string s=mul(54,3);//s=“666”
但这个不会:

short n2 = mul<short>(6, 3); // error: assignment of read-only variable ‘k’
short n2=mul(6,3);//错误:只读变量“k”的赋值
通过模板化返回值2显式区分调用 嘿,你也作弊了

对,我对两个“重载”函数使用了相同的参数。但是你开始作弊了(见上文)

^_^

更严重的是,如果需要不同的参数,则需要编写更多的代码,然后在调用函数时必须显式使用正确的类型以避免歧义:

// For "int, int" calls
template<typename T>
T mul(int i, int j)
{
   // If you get a compile error, it's because you did not use
   // one of the authorized template specializations
   const int k = 25 ; k = 36 ;
}

template<>
int mul<int>(int i, int j)
{
   return i * j ;
}

// For "char, int" calls
template<typename T>
T mul(char i, int j)
{
   // If you get a compile error, it's because you did not use
   // one of the authorized template specializations
   const int k = 25 ; k = 36 ;
}

template<>
std::string mul<std::string>(char i, int j)
{
   return std::string(j, (char) i) ;
}
//用于“int,int”调用
模板
T mul(int i,int j)
{
//如果出现编译错误,那是因为没有使用
//授权的模板专门化之一
常数int k=25;k=36;
}
模板
int mul(int i,int j)
{
返回i*j;
}
//对于“char,int”调用
模板
T mul(字符i,整数j)
{
//如果出现编译错误,那是因为没有使用
//授权的模板专门化之一
常数int k=25;k=36;
}
模板
std::string mul(字符i,int j)
{
返回std::字符串(j,(char)i);
}
该代码将被用作:

int n = mul<int>(6, 3); // n = 18
std::string s = mul<std::string>('6', 3); // s = "666"
int n=mul(6,3);//n=18
std::string s=mul('6',3);//s=“666”
以及以下一行:

short n2 = mul<short>(6, 3); // n = 18
short n2=mul(6,3);//n=18
仍然无法编译

结论 我喜欢C++……/P>
:-p

如果您想使
mul
成为一个真正的函数而不是一个类,您可以使用一个中间类:

class StringOrInt
{
public:
    StringOrInt(int p1, int p2)
    {
        param1 = p1;
        param2 = p2;
    }
    operator int ()
    {
        return param1 * param2;
    }

    operator std::string ()
    {
        return std::string(param2, param1 + '0');
    }

private:
    int param1;
    int param2;
};

StringOrInt mul(int p1, int p2)
{
    return StringOrInt(p1, p2);
}
这允许您将
mul
作为函数传递到std算法中:

int main(int argc, char* argv[])
{
    vector<int> x;
    x.push_back(3);
    x.push_back(4);
    x.push_back(5);
    x.push_back(6);

    vector<int> intDest(x.size());
    transform(x.begin(), x.end(), intDest.begin(), bind1st(ptr_fun(&mul), 5));
    // print 15 20 25 30
    for (vector<int>::const_iterator i = intDest.begin(); i != intDest.end(); ++i)
        cout << *i << " ";
    cout << endl;

    vector<string> stringDest(x.size());
    transform(x.begin(), x.end(), stringDest.begin(), bind1st(ptr_fun(&mul), 5));
    // print 555 5555 55555 555555
    for (vector<string>::const_iterator i = stringDest.begin(); i != stringDest.end(); ++i)
        cout << *i << " ";
    cout << endl;

    return 0;
}
intmain(intargc,char*argv[])
{
向量x;
x、 推回(3);
x、 推回(4);
x、 推回(5);
x、 推回(6);
向量intDest(x.size());
转换(x.begin(),x.end(),intDest.begin(),bind1st(ptr_-fun(&mul),5));
//打印15 20 25 30
for(vector::const_迭代器i=intDest.begin();i!=intDest.end();++i)
好吧,你们这些天才们,这就是你们像职业选手一样做这件事的方式


class mul
{
 int m_i,m_j;
public:
 mull(int i,int j):m_i(i),m_j(j){}
 template
 operator R() 
 {
  return (R)m_i * m_j;
 }
};


double d = mul(1,2);
long l = mul(1,2);
别傻了

class mul
{
 int m_i,m_j;
public:
 mull(int i,int j):m_i(i),m_j(j){}
 template
 operator R() 
 {
  return (R)m_i * m_j;
 }
};

double d = mul(1,2);
long l = mul(1,2);
//This is not valid
    int foo();
    float foo();

    typedef int Int;

    int foo(int j);
    int foo(Int j);

//Valid:
   int foo(int j);
   char* foo(char * s);
   int foo(int j, int k);
   float foo(int j, float k);
   float foo(float j, float k);