今天在编译项目时,代码审查提示 “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++ 参考手册如下解释

  1. 指定构造函数或转换函数 (C++11起)为显式, 即它不能用于隐式转换复制初始化.
  2. explicit 指定符可以与常量表达式一同使用. 函数若且唯若该常量表达式求值为 true 才为显式. (C++20起)

也就是构造函数被 explicit 修饰后, 就不能再被隐式调用了

等于说,std::vector<file> files = d 这样的操作禁止使用了,只能 std::vector<file> files = files{d}

Effective C++中也阐述了:

被声明为 explicit的构造函数通常比其 non-explicit 兄弟更受欢迎, 因为它们禁止编译器执行非预期 (往往也不被期望) 的类型转换. 除非我有一个好理由允许构造函数被用于隐式类型转换, 否则我会把它声明为 explicit. 我鼓励你遵循相同的政策.

"explicit" 的使用的更多相关文章

  1. 可空类型(Nullable<T>)及其引出的关于explicit、implicit的使用

    问题一:Nullable<T>可赋值为null 先看两行C#代码 int? i1 = null; int? i2 = new int?(); int? 即Nullable<int&g ...

  2. 关于Django 错误 doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS

    记录一下 报错 doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS\ 这个问题出现没 ...

  3. 显示转换explicit和隐式转换implicit

    用户自定义的显示转换和隐式转换 显式转换implicit关键字告诉编译器,在源代码中不必做显示的转型就可以产生调用转换操作符方法的代码. 隐式转换implicit关键字告诉编译器只有当源代码中指定了显 ...

  4. explicit抑制隐型转换

    本文出自 http://www.cnblogs.com/cutepig/ 按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: clas ...

  5. C++ explicit关键字详解

    本文系转载,原文链接:http://www.cnblogs.com/ymy124/p/3632634.html 首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用 ...

  6. Implicit and Explicit Multithreading MULTITHREADING AND CHIP MULTIPROCESSORS

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION The concept of thread ...

  7. 【Android 疑难杂症1】android.content.ActivityNotFoundException: Unable to find explicit activity class

    android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.cnote ...

  8. C++笔记(1)explicit构造函数

    按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: class String { String ( const char* p );  ...

  9. C++中explicit关键字的使用

    看书看到了explicit关键字,就来做个笔记,讲得比较明白,比较浅. 在C++中,我们有时可以将构造函数用作自动类型转换函数.但这种自动特性并非总是合乎要求的,有时会导致意外的类型转换,因此,C++ ...

  10. 错误:Implicit super constructor xx() is undefined for default constructor. Must define an explicit constructor

    错误:Implicit super constructor xx() is undefined for default constructor. Must define an explicit con ...

随机推荐

  1. [转帖]Oracle JDBC中的语句缓存

    老熊 Oracle性能优化 2013-09-13 在Oracle数据库中,SQL解析有几种: 硬解析,过多的硬解析在系统中产生shared pool latch和library cache liatc ...

  2. [转帖]zookeeper三节点集群搭建

    https://www.jianshu.com/p/1dcfbf45383b 下载zookeeper Apache源 http://archive.apache.org/dist/zookeeper/ ...

  3. [转帖]TiKV读写流程浅析

    https://www.cnblogs.com/luohaixian/p/15227838.html 1.TiKV框架图和模块说明 图1  TiKV整体架构图 1.1.各模块说明 PD Cluster ...

  4. [转帖]如何部署windows版本的oswatcher

    2017-02-22 没有评论 windows上也有os watcher:OSWFW. 目前支持的windows版本是: Windows XP (x86 & x64)Windows 7 (x8 ...

  5. [转帖]jmeter 使用beanshell 编写脚本

    目录 一.介绍 1.1 介绍 1.2 下载&启动 二.jmeter中创建beanshell脚本 三.jmeter与beanshell 数据交互 3.1 例子1 beanshell 将变量传给j ...

  6. Navicat For Redis 的学习与使用

    Navicat For Redis 的学习与使用 背景 周末在家看了几个公众号: 说到Navicat 16.2已经有了 Redis的客户端. 想着前段时间一直在学习Redis, 但是没有GUI的工具, ...

  7. [转帖]SPECjvm2008 User's Guide

    SPECjvm2008 User's Guide https://spec.org/jvm2008/docs/UserGuide.html#UsePJA Version 1.0Last modifie ...

  8. dmidecode 查看内存以及硬件信息

    安装工具dmidecode 使用 1.查看内存槽及内存条 $ sudo dmidecode -t memory 2.查看内存的插槽数,已经使用多少插槽.每条内存多大 $ sudo dmidecode  ...

  9. Linux 界面能够出现ip地址提示的方法

    cat <<EOF >/etc/profile.d/ip.sh if [[ `tty | grep "pts"` ]]; then export PS1='['& ...

  10. 【1】Pycharm 主题设置推荐Material Theme UI以及编辑环境配置(字体大小和颜色)

    相关文章: [1]Pycharm 主题设置推荐Material Theme UI以及编辑环境配置(字体大小和颜色) [2]Pycharm插件推荐,超级实用!每个小trick都可以快速提升变成效率! [ ...