C++ C++;如果其中一个参数是字符串,则返回类型等于字符串

C++ C++;如果其中一个参数是字符串,则返回类型等于字符串,c++,templates,C++,Templates,此函数应至少接受3种类型:string、int和double。 它应该将lval添加到rval并返回该值。问题是,如果其中一个是字符串,则应该将这些值串联起来 示例:lval=1,rval=“Bruce”,return=“1Bruce” 示例:lval=“Tom”,rval=2,return=“Tom2” 示例:lval=1,rval=3.0,return=4.0 我试图添加第三个名为T的类型名,并将其用作AddObject类型,但这只是抛出了未识别的T错误 template<typena

此函数应至少接受3种类型:string、int和double。 它应该将lval添加到rval并返回该值。问题是,如果其中一个是字符串,则应该将这些值串联起来

示例:lval=1,rval=“Bruce”,return=“1Bruce”

示例:lval=“Tom”,rval=2,return=“Tom2”

示例:lval=1,rval=3.0,return=4.0

我试图添加第三个名为T的类型名,并将其用作AddObject类型,但这只是抛出了未识别的T错误

template<typename L, typename R>
static L AddObject(L lval, R rval){
    return lval + rval;
};
模板
静态L AddObject(L lval,R rval){
返回lval+rval;
};
编辑:实现的解决方案代码

#include <string>
#include <sstream>

using namespace std;

class MathFuncs{
public:

    /.../

    template<typename L, typename R>
    static auto do_add(L lval, R rval, false_type){
        return lval + rval;
    }

    template<typename L, typename R>
    static string do_add(L lval, R rval, true_type){
        ostringstream oss;
        oss << lval << rval;
        return oss.str();
    }

    /*
     * Addition function.
     */
    template<typename L, typename R>
    static auto add(L lval, R rval){
        using dispatch_type = integral_constant<
            bool, 
            is_convertible<L, string>{}
            || is_convertible<R, string>{} >;
        return do_add(lval, rval, dispatch_type());
    }
};
#包括
#包括
使用名称空间std;
类MathFuncs{
公众:
/.../
模板
静态自动添加(左、右、假类型){
返回lval+rval;
}
模板
静态字符串do_add(L lval、R rval、true_类型){
ostringstream oss;

ossC++是一种强类型语言。如果你想做这种事情,你需要简洁地指定你想做的动作(添加或连接)在所有参数排列的情况下,确保为每种参数排列提供专门化。在混合字符串和数字类型的情况下,还必须决定是否要将数字转换为字符串,并将两者视为文本和串联

例如:

template<>
static std::string AddObject<std::string, int>(string lval, int rval){
    std::ostringstream oss;
    oss << lval << rval;
    return oss.str();
};
但是

根据您输入的来源,这可能并不明显。

您在寻找什么

template<typename L, typename R>
static auto AddObject(L lval, R rval) -> decltype(lval + rval)
{
    return lval + rval;
};
模板
静态自动添加对象(L lval,R rval)->decltype(lval+rval)
{
返回lval+rval;
};
或者,使用C++14

template<typename L, typename R>
static auto AddObject(L lval, R rval)
{
    return lval + rval;
};
模板
静态自动添加对象(L lval,R rval)
{
返回lval+rval;
};

这种返回类型取决于要重载的是什么。

< P> > C++ >

一切皆有可能。
#include <type_traits>
#include <iostream>

template <class B>
typename std::enable_if < std::is_same<B,int>::value ||std::is_same<B,double>::value ,std::string   >::type
 add (std::string str , B b){
 return str + std::to_string(b);    
}

template <class B>
typename std::enable_if < std::is_same<B,int>::value ||std::is_same<B,double>::value  ,std::string   >::type
 add (B b, std::string str){
 return std::to_string(b)+ str ;    
}

template <class A , class B>
typename std::enable_if < (std::is_same<B,int>::value ||std::is_same<B,double>::value)&& (std::is_same<A,int>::value ||std::is_same<A,double>::value) , decltype(A()+B())  >::type
 add (B b, A a){
 return a+b;  
}

std::string add (std::string a , std::string b){
return a+b;    
} 

int main (void){
 std::cout << add("hi ", "there")<<"\n";
 std::cout << add ("hi there" , 3)<<"\n";
 std::cout << add (3 , "hi there")<<"\n";
 std::cout << add (2.2 , 1.1)<<"\n";
 std::cout << add (3.14 , 2)<<"\n";
 std::cout << add (4 , 2)<<"\n";
return 0;    
}
#包括
#包括
模板
如果::type,则启用
添加(std::string str,B){
返回str+std::to_字符串(b);
}
模板
如果::type,则启用
添加(B,std::string str){
返回std::to_字符串(b)+str;
}
模板
typename std::enable_if<(std::is_same::value | std::is_same::value)&&(std::is_same

标记分派:

template<class A, class B>
auto do_add(A a, B b, std::false_type /*has_string*/) { return a + b; }

template<class A, class B>
std::string do_add(A a, B b, std::true_type /*has_string*/) {
   std::ostringstream oss; 
   oss << a << b; 
   return oss.str();
}

template<class A, class B>
auto add(A a, B b) {
    using dispatch_type = std::integral_constant<bool, 
                                   std::is_convertible<A, std::string>{}
                                || std::is_convertible<B, std::string>{}>;
    return do_add(a, b, dispatch_type());
}
模板
自动添加(A,B,std::false_type/*具有_string*/){返回A+B;}
模板
std::string do_add(A、B、std::true_type/*具有_string*/){
std::ostringstream oss;

OSS,即使使用模板,这也是不可能的。在这种情况下,我将不得不找出一些东西。当然是可能的,但是用一个弱类型的语言(比如JavaScript)来实现可能更容易。C++的一个优点是它强迫你详细地思考你正在做的事情和相应的代码。LLY会带来更好的代码。你提到JavaScript是很有趣的,因为这个项目是关于编译一个编译器,它把JavaScript翻译成机器代码。我现在只是在测试可能性。不是我完全同意,JavaCrPiter实际上是用C/C++编写的。这并不能使C++成为一个动态的Lype类型的LAN。但是,你可以做很多模板来模仿它。我认为C++中没有什么是不可能的。我要去谷歌,然后在回答之前测试你的建议。类型演绎是相当友好的,特别是在C++ 14中。这里的技巧在于定义你想添加的各种组合的操作符+,例如:STD::(std::string-lhs,double-rhs){/**}哦,在那一点上,我必须重载+运算符才能实现这一点?太棒了!谢谢!我只有一个问题。有可能使它更优雅吗?我将尝试实现@JonChesterfield建议的版本,如果它不起作用(据我所知)我会使用你的建议。嗯,如果你稍微使用std::enable_if,你可以把它缩短一些。老实说,我看不出Jon Chesterfield代码实际上是如何工作或编译的。
decltype(std::string+int)没有用任何C++标准的方式定义。我认为这是迄今为止最好的选择。我喜欢这个样子。很容易理解。不幸的是,我需要离开几个小时。我会在回来的时候测试它。但现在我将它标记为解决方案。非常感谢!
#include <type_traits>
#include <iostream>

template <class B>
typename std::enable_if < std::is_same<B,int>::value ||std::is_same<B,double>::value ,std::string   >::type
 add (std::string str , B b){
 return str + std::to_string(b);    
}

template <class B>
typename std::enable_if < std::is_same<B,int>::value ||std::is_same<B,double>::value  ,std::string   >::type
 add (B b, std::string str){
 return std::to_string(b)+ str ;    
}

template <class A , class B>
typename std::enable_if < (std::is_same<B,int>::value ||std::is_same<B,double>::value)&& (std::is_same<A,int>::value ||std::is_same<A,double>::value) , decltype(A()+B())  >::type
 add (B b, A a){
 return a+b;  
}

std::string add (std::string a , std::string b){
return a+b;    
} 

int main (void){
 std::cout << add("hi ", "there")<<"\n";
 std::cout << add ("hi there" , 3)<<"\n";
 std::cout << add (3 , "hi there")<<"\n";
 std::cout << add (2.2 , 1.1)<<"\n";
 std::cout << add (3.14 , 2)<<"\n";
 std::cout << add (4 , 2)<<"\n";
return 0;    
}
template<class A, class B>
auto do_add(A a, B b, std::false_type /*has_string*/) { return a + b; }

template<class A, class B>
std::string do_add(A a, B b, std::true_type /*has_string*/) {
   std::ostringstream oss; 
   oss << a << b; 
   return oss.str();
}

template<class A, class B>
auto add(A a, B b) {
    using dispatch_type = std::integral_constant<bool, 
                                   std::is_convertible<A, std::string>{}
                                || std::is_convertible<B, std::string>{}>;
    return do_add(a, b, dispatch_type());
}