从 char 数组类型推导到 std::string
type deduction from char array to std::string
我正在尝试使用可变参数模板编写 sum
函数。
在代码中我会写类似
sum(1, 2., 3)
并且它将 return 最一般的总和类型(在本例中 - 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!
最终,您 char
指针类型不能很好地同时位于 operator +
的左侧 和 右侧。` 你可以如果需要,超载以制造中介。
下面我冒昧地将其重构为支持单参数的 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!
祝你好运
我只想编写一个简单的重载身份函数来专门处理 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...);
}
我正在尝试使用可变参数模板编写 sum
函数。
在代码中我会写类似
sum(1, 2., 3)
并且它将 return 最一般的总和类型(在本例中 - 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!
最终,您 char
指针类型不能很好地同时位于 operator +
的左侧 和 右侧。` 你可以如果需要,超载以制造中介。
下面我冒昧地将其重构为支持单参数的 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!
祝你好运
我只想编写一个简单的重载身份函数来专门处理 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...);
}