c++可变参数联接路径
c++ variadic parameter join path
我试图用可变模板编写一个连接路径函数。我是这样做的:
template<typename T>
T&& join_path (T&& path) {
return path;
}
template<typename T, typename ... Args>
std::string join_path (T&& path1, Args&& ... paths)
{
static_assert(std::is_same<typename std::decay<T>::type, std::string>::value ||
std::is_same<typename std::decay<T>::type, const char *>::value,
"T must be a basic_string");
std::string p2 = join_path(std::forward<Args>(paths)...);
if (!p2.empty() && p2[0] == '/')
return path1 + p2;
return path1 + '/' + p2;
}
但有一个问题,当我传递像join_path("system", path)
这样的字符串文字时,T被认为是const char *
。所以我不能使用+运算符。我该怎么修?
我想到的一个解决方案是return std::string(path1) + '/' + p2;
。但它不会引入额外的复制吗?
您可以使用std::string_view
,因为C++17:
std::string join_path(std::initializer_list<std::string_view> paths)
{
std::string res;
const char* sep = "";
for (auto p : paths) {
res += (!p.empty() && p[0] == '/') ? "" : sep
res += p;
sep = "/";
}
return res;
}
template<typename ... Ts>
std::string join_path (Ts&&... paths)
{
static_assert(((std::is_same<typename std::decay<Ts>::type, std::string>::value ||
std::is_same<typename std::decay<Ts>::type, const char *>::value) || ...),
"T must be a basic_string");
return join_path({paths...});
}
演示
为了避免std::string(std::string)
的情况,请通过Simple查看此解决方案。它比您的解决方案和Kostas的解决方案工作得更快。
以下是针对您的用例修改的解决方案:
inline std::string const& to_string(std::string const& s) { return s; }
template<typename... Args>
std::string join_path(Args const&... args)
{
std::string result;
std::string s;
using ::to_string;
using std::to_string;
int unpack[]{0, (result += ((!(s = to_string(args)).empty() && s[0]=='/') ? "" : "/") + s, 0)...};
static_cast<void>(unpack);
return result;
}
除此之外,如果你担心std::string(const char*)
,那么我认为这是不容易避免的。
您可以显式地将第一个参数强制转换为std::string
。你可以通过使用折叠表达式(C++17(来确保它不会重复:
template<class ... Strings>
std::string join_path (std::string path, Strings&& ... paths)
{
path += ((std::string(paths) + '/') + ...);
if constexpr (!sizeof...(paths))
path1.pop_back(); // remove last /
return path;
}
附言:你可以用std::decay_t<T>
代替typename std::decay<T>::type
。
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 创建进程使用路径时出现错误事件:类型 "char *" 的 E0167 参数与类型 "LPWSTR" 的参数不兼容
- C 能够以其完整路径打开代码::块中的文件,但不能以相对路径作为命令行参数打开文件
- 从文件名中提取文件名,路径来自参数
- 使用 php 将带有命令行可执行文件路径的参数传递
- 如何将执行路径与文件路径和参数分开
- 向文件名参数(LPCSTR)添加预先声明的路径
- 从net.connman.Manager的GetService方法动态提取D-Bus参数和对象路径
- 添加文件路径参数
- Train_hog.cpp OpenCV 3.1 示例 - 无法传递正确的路径参数
- 缩短C++枚举成员的路径(使用 typedef 或 typename),以用作模板参数
- 更改系统命令参数的路径
- 如何将带有空格作为参数的路径添加到CreateProcess批处理文件中
- 如何在vc++中将路径作为参数传递到第二个应用程序中
- 在源文件中指定include前缀与在编译器的搜索路径参数中指定include前缀的优缺点是什么
- 如何将目录中所有具有完整路径的文件传递到execv中的参数数组
- 当构造函数具有相同的参数类型(文件路径)时,如何从数组创建(初始化)std::元组
- 在参数列表中使用绝对路径启动QProcess