"explicit" 的使用
作者:互联网
今天在编译项目时,代码审查提示 “Single-parameter constructors should be marked explicit”
于是就在构造函数前加上 explicit
下面为最小的示例,这个示例主要是按文件创建时间排序并删除过期的文件
#include <iostream> #include <thread> #include <windows.h> #include <exception> #include <vector> #include <filesystem> wchar_t file_path[] = L"D:/VS2019_Program/Test_SetUnhandledExceptionFilter/Debug/.sentry-native/reports/"; wchar_t file_ext[] = L".dmp"; std::vector<std::wstring> TraverseFolder(std::wstring folder_path, std::wstring ext); class file { public: std::wstring name; FILETIME time; public: bool operator<(file const& other) const { return CompareFileTime(&other.time, &time) == 1; } file(WIN32_FIND_DATA const &d) : name(d.cFileName), time(d.ftCreationTime) {} }; std::vector<file> SortDumpFiles(std::vector<std::wstring> dumpfiles) { std::vector<file> files; std::transform(dumpfiles.begin(), dumpfiles.end(), std::back_inserter(files), [](std::wstring const &fname) { WIN32_FIND_DATA d; HANDLE h = FindFirstFile(fname.c_str(), &d); FindClose(h); return d; }); std::sort(files.begin(), files.end()); return files; } void DelExpiredDumpFiles() { std::wstring path(file_path); std::wstring ext(file_ext); auto dump_file = TraverseFolder(path, ext); int total_file = dump_file.size(); int to_be_deleted = total_file - 4; if (to_be_deleted <= 0) { return; } // 以文件创建时间 auto files = SortDumpFiles(dump_file); while (to_be_deleted--) { std::wstring file = file_path; file += files[to_be_deleted].name; if (!DeleteFile(file.c_str())) { int err = GetLastError(); return; } } } std::vector<std::wstring> TraverseFolder(std::wstring folder_path, std::wstring ext) { std::vector<std::wstring> filename; if (!std::filesystem::is_directory(folder_path)) { return filename; } for (auto& p : std::filesystem::recursive_directory_iterator(folder_path)) { if (p.path().extension() == ext) { filename.push_back(p.path().wstring()); } } return filename; } int main() { DelExpiredDumpFiles(); return 0; }
添加 explicit 关键词
explicit file(WIN32_FIND_DATA const &d) : name(d.cFileName), time(d.ftCreationTime) {}
编译会报错,
解决方法,
std::transform(dumpfiles.begin(), dumpfiles.end(), std::back_inserter(files), [](std::wstring const &fname) { WIN32_FIND_DATA d; HANDLE h = FindFirstFile(fname.c_str(), &d); FindClose(h); return file{d}; });
原因:
explicit 关键字
- 指定构造函数或转换函数 (C++11起)为显式, 即它不能用于隐式转换和复制初始化.
- explicit 指定符可以与常量表达式一同使用. 函数若且唯若该常量表达式求值为 true 才为显式. (C++20起)
也就是构造函数被 explicit 修饰后, 就不能再被隐式调用了
等于说,std::vector<file> files = d 这样的操作禁止使用了,只能 std::vector<file> files = files{d}
Effective C++中也阐述了:
被声明为explicit
的构造函数通常比其 non-explicit 兄弟更受欢迎, 因为它们禁止编译器执行非预期 (往往也不被期望) 的类型转换. 除非我有一个好理由允许构造函数被用于隐式类型转换, 否则我会把它声明为explicit
. 我鼓励你遵循相同的政策.
标签:std,files,explicit,wstring,file,使用,path 来源: https://www.cnblogs.com/strive-sun/p/16401861.html