如何编写模板函数来添加整数但是连接字符串和字符类型?

时间:2017-07-14 12:52:16

标签: c++ string

我正在尝试编写一个泛型函数(使用模板)来添加整数和在字符串或字符串的情况下连接。 以下工作正常使用字符串和整数但它不适用于字符。

string operator+(char a,char b)
{
        string c= string(1,a) + string(1,b);
        cout<<c;
        return c;
}


template<typename T>
void add(T a,T b)
{
        cout<<endl;
        cout<<a+b;
        cout<<endl;
}

int main()
{
        //string a="Stack",b=" Overflow"; //Works fine
        //int a=1,b=2; //Works fine
        char a='a',b='b'; //ISSUE HERE
        add(a,b);
        return 0;;
};

对于字符,它添加了ascii而不是连接。 因此我重载了运营商&#39; +&#39;添加两个char。

string operator+(char a,char b)
{
        string c= string(1,a) + string(1,b);
        cout<<c;
        return c;
}

但似乎我们甚至无法通过重载运算符来添加两个内置类型。

typecast_overloading.cpp:5: error: âstd::string operator+(char, char)â must have an argument of class or enumerated type

那么,我该怎么做?

编辑:这不是&#34;我可以重载内置&#34;类型。我知道我做不到。我只是展示了我尝试过的东西以及没有用的东西。可能是没有超载的预期结果。我期待着其他方式。

2 个答案:

答案 0 :(得分:1)

C ++标准不允许

std::string operator+(char, char)(你不能为内置类型重载运算符)。

但您可以为void add(T a, T b)类型专门化 char

template<>
void add(char a, char b)
{
    std::cout << a << b;
}

答案 1 :(得分:1)

备选方案1:添加重载。它将在模板函数中选择,因为它更具体。

string add( char a, char b )
{
    return string( 1, a ) + b;
}

备选方案2:使用部分专业化。 (完整模板示例)

#include <iostream>
#include <string>

template<typename T>
struct adder_t
{
    auto operator()(T const &a, T const &b) const
        -> decltype(a + b)
    {
        return a + b;
    }
};

template<>
struct adder_t<char>
{
    std::string operator()(char a, char b) const
    {
        return std::string(1, a) + b;
    }
};

template< typename T >
auto add(T &&a, T &&b)
-> decltype(std::declval<adder_t<typename std::decay<T>::type>>()(a, b))
{
    adder_t<typename std::decay<T>::type> adder;
    return adder(std::forward<T>(a), std::forward<T>(b));
}

int main()
{
    std::string sa = "aaa", sb = "bbb";
    char ca = 'a', cb = 'b';
    int ia = 12, ib = 34;

    std::cout << add(sa, sb) << "\n";
    std::cout << add(ca, cb) << "\n";
    std::cout << add(ia, ib) << "\n";

    return 0;
}