C++ C++;如果其中一个参数是字符串,则返回类型等于字符串
此函数应至少接受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错误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
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());
}