1. CMake在某一个target中清空include_directory
我们都知道,现代CMake是面向target的。在设置target的头文件搜索路径时,也推荐使用target_include_directory单独为某个target设置头文件搜索路径,并同时设置路径对其他目标的可见性(private, interface…)。
但如果你在参与一个有一定历史的大型项目,其CMake可能经历了好“几代”程序员的维护,就有可能出现target_include_directory与include_directory混用的情况。如果恰巧两个目标里面,又有同名的头文件,就会出现诡异的事情了 :(
有没有办法解决这种问题呢?
有,使用CMake的set_property。
例:
set_property(
TARGET
target_name
PROPERTY
INCLUDE_DIRECTORIES ""
)
可以看到,通过set_property将INCLUDE_DIRECTORIES属性设置为空就ok啦
需要注意的是set_property的顺序,不要将想要添加的路径也清空呀
2. C++大括号初始化与初始化列表及窄化类型转换
首先来看一段示例代码:
auto count_unique(const std::array<int32_t, 3>& v)
{
return std::unordered_set<bool>{v.begin(), v.end()}.size();
}
auto ret = count_unique({0, 1, 2})
Q:请问这段代码得到的set中,有哪些元素呢?
符合直觉地,我们可能会回答:
2个元素: true, false.因为0类型转换为了false,1和2转换为了true
但答案却是:
1个元素.
因为如果有初始化列表为参数的构造函数,大括号初始化就会优先匹配初始化列表为参数的构造函数.
不幸的是,在这段代码中,编译器认为unordered_set的这个这个大括号初始化应该匹配初始化列表为参数的构造函数.
而在libc++ 及 libstdc++的实现中,v.begin() v.end() 为指针.因此,编译器将这两个指针强转为了bool.即,我们其实使用了两个bool值来初始化这个容器.
如何解决这个问题?
我们可以将指针到bool的类型转换定义为"窄化"的.
那为什么"窄化"的类型转换就可以避免这个问题了呢?
因为在初始化列表的参数,是不接受"窄化"的类型转换的,即如果指针到bool的类型转换定义为"窄化"的,我们的这段代码将会通不过编译.