有时,c ++默认允许切片可能会令人烦恼。例如
struct foo { int a; };
struct bar : foo { int b; };
int main() {
bar x{1,2};
foo y = x; // <- I dont want this to compile!
}
Run Code Online (Sandbox Code Playgroud)
这将编译并按预期运行!但是,如果我不想启用切片怎么办?
什么是惯用的写法,foo以至于无法对任何派生类的实例进行切片?
以下代码编译正常,没有任何警告(使用g ++的默认选项).在这种情况下,是否有一个标志可以用来让g ++发出警告?
void foo(bool v) {
}
void bar() {
foo("test");
}
Run Code Online (Sandbox Code Playgroud) 考虑以下函数模板声明:
template <typename T, typename = std::enable_if_t<std::is_same_v<T, int>>>
void foo(T i);
Run Code Online (Sandbox Code Playgroud)
这个模板只有一个可能的有效实例,即with T = int.我想把这个定义放在一个实现文件中.我可以想到两种可能的方法.(如果你想知道为什么我会这样做而不只是说void foo(int i),这是因为模板版本阻止了呼叫站点的隐式转换.)
方法1:
我可以使用extern template声明来告诉在其他foo<int>()地方实例化的其他TU :
// In foo.hpp
template <typename T, typename = std::enable_if_t<std::is_same_v<T, int>>>
void foo(T i);
extern template void foo(int);
// In foo.cpp
template <typename T, typename>
void foo(T i) { ... } // full template definition
template void foo(int); // explicit instantiation with T = int
Run Code Online (Sandbox Code Playgroud)
方法2:
我可以为int案例提供明确的专业化:
// In foo.hpp
template …Run Code Online (Sandbox Code Playgroud)