类型从字符阵列到std :: string

type deduction from char array to std::string

本文关键字:std string 阵列 字符 类型      更新时间:2023-10-16

我正在尝试使用variadic模板编写sum函数。在代码中,我会写

之类的东西
sum(1, 2., 3)

它将返回总和的大多数通用类型(在这种情况下-double)。问题是字符。当我称其为

sum("Hello", " ", "World!") 

模板参数被描述为const char [7],因此不会编译。我找到了将最后一个参数指定为 std::string("World!")的方法,但是它不是很漂亮,是否有任何方法可以将自动类型扣除到 std::string或正确地超载 sum

我到目前为止的代码:

template<typename T1, typename T2>
auto sum(const T1& t1, const T2& t2) {
    return t1 + t2;
}
template<typename T1, typename... T2>
auto sum(const T1& t1, const T2&... t2) {
    return t1 + sum(t2...);
}
int main(int argc, char** argv) {
    auto s1 = sum(1, 2, 3);
    std::cout << typeid(s1).name() << " " << s1 << std::endl;
    auto s2 = sum(1, 2.0, 3);
    std::cout << typeid(s2).name() << " " << s2 << std::endl;
    auto s3 = sum("Hello", " ", std::string("World!"));
    std::cout << typeid(s3).name() << " " << s3 << std::endl;
    /* Won't compile! */
    /*
    auto s4 = sum("Hello", " ", "World!");
    std::cout << typeid(s4).name() << " " << s4 << std::endl;
    */
    return 0;
}

输出:

i 6
d 6
Ss Hello World!

我只会编写一个简单的过载身份函数,该功能专门处理const char*

template<typename T>
decltype(auto) fix(T&& val)
{
    return std::forward<T>(val);
} 
auto fix(char const* str)
{
    return std::string(str);
}
template<typename T1, typename T2>
auto sum(const T1& t1, const T2& t2) {
    return fix(t1) + t2;
}
template<typename T1, typename... T2>
auto sum(const T1& t1, const T2&... t2) {
    return t1 + sum(t2...);
}

最终您的char指针类型不能很好地处理在operator +的左右侧。如果需要。

在下面,我将Liberty重构为单帕拉姆支持的sum(不是必需的步骤,但允许sum(x)超载,这更清楚地理解)。希望您能得到这个主意。

#include <iostream>
#include <string>
// generic identity
template<typename T1>
auto sum(const T1& t1)
{
    std::cout << __PRETTY_FUNCTION__ << 'n';
    return t1;
}
// specialized for const char [N]
auto sum(const char *s)
{
    std::cout << __PRETTY_FUNCTION__ << 'n';
    return std::string(s);
}
template<typename T1, typename... T2>
auto sum(const T1& t1, const T2&... t2)
{
    std::cout << __PRETTY_FUNCTION__ << 'n';
    return t1 + sum(t2...);
}
int main(int argc, char** argv) {
    std::cout << sum(1,2,3) << 'n';
    std::cout << sum(1, 2.0, 3) << 'n';
    std::cout << sum("Hello", " ", std::string("World!")) << 'n';
    std::cout << sum("Hello", " ", "World!");
    return 0;
}

输出

auto sum(const T1 &, const T2 &...) [T1 = int, T2 = <int, int>]
auto sum(const T1 &, const T2 &...) [T1 = int, T2 = <int>]
auto sum(const T1 &) [T1 = int]
6
auto sum(const T1 &, const T2 &...) [T1 = int, T2 = <double, int>]
auto sum(const T1 &, const T2 &...) [T1 = double, T2 = <int>]
auto sum(const T1 &) [T1 = int]
6
auto sum(const T1 &, const T2 &...) [T1 = char [6], T2 = <char [2], std::__1::basic_string<char>>]
auto sum(const T1 &, const T2 &...) [T1 = char [2], T2 = <std::__1::basic_string<char>>]
auto sum(const T1 &) [T1 = std::__1::basic_string<char>]
Hello World!
auto sum(const T1 &, const T2 &...) [T1 = char [6], T2 = <char [2], char [7]>]
auto sum(const T1 &, const T2 &...) [T1 = char [2], T2 = <char [7]>]
auto sum(const char *)
Hello World!

最佳幸运