如果参数之一是字符串,则C 返回类型等于字符串

C++ return type equals string if one of the parameters is a string

本文关键字:字符串 返回类型 如果 参数      更新时间:2023-10-16

此功能至少应接受3种类型:字符串,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;
};

编辑:实现的解决方案代码。

#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());
    }
};

标签调度:

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());
}

您是否正在寻找

template<typename L, typename R>
static auto AddObject(L lval, R rval) -> decltype(lval + rval)
{
    return lval + rval;
};

或,使用C 14,

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

这样,返回类型取决于 被超载为be。

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;    
}

可以在此处查看:http://coliru.stacked-crooked.com/a/a/971d38aaebad2954

c 是一种强烈打字的语言。如果您想做这种事情,则需要简单地指定要在所有参数排列的情况下(添加或连接)的操作,并确保您为每个参数提供专业化。如果要将数字转换为字符串并将其视为文本和串联。

例如:

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

您当然可以将函数作为第三个参数将可以执行"行动"的参数,尽管这将实现什么好处,但我不确定,因为呼叫者将不得不选择和注入一种方法,而不是将其封装(这似乎是此模板函数的重点)

从总体设计的角度来看,我建议不要将其视为一般情况。如果您想绝对要清楚它会做什么,则必须同样定义此调用的代码。例如,它必须知道

AddObject( 1.0, 2.0 ) == 3.0

但是

AddObject( "1.0", "2.0" ) == "1.02.0"

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