看看之前的答案,似乎虽然std::ostream不是可移动的,但std::ofstream应该是.但是,这段代码
#include <fstream>
int main()
{
std::ofstream ofs;
std::ofstream ofs2{std::move(ofs)};
}
Run Code Online (Sandbox Code Playgroud)
似乎没有在我试过的任何版本的gcc或clang中编译(使用--std = c ++ 11或--std = c ++ 14).编译器错误有所不同,但这是我得到的gcc 4.9.0
6 : error: use of deleted function 'std::basic_ofstream::basic_ofstream(const std::basic_ofstream&)'
Run Code Online (Sandbox Code Playgroud)
根据标准,这是预期的行为吗?
请注意,之前问过一个非常类似的问题(std :: ofstream是否可以移动?)但是从那时起标准似乎发生了变化(详见 为什么不能移动std :: ostream?)使这些答案过时.当然,这些答案都没有解释为什么上面的代码不能编译.
在尝试使用容器时遇到了这个问题ofstream,因为上述情况不起作用.
假设我有以下定义:
int f(int ) { return 1; } // a)
template<typename T> int f(T x) { return 2; } // b)
Run Code Online (Sandbox Code Playgroud)
我明白,如果我打电话f,例如f(1),非模板重载a)将是首选,但是有没有办法明确地引用a)?例如,我可以用来f<int>明确地参考b).
作为为什么这会有用的一个例子,请考虑以下函数:
template<typename Func, typename T> void print_result(Func f, T arg)
{
std::cout << f(arg) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用它f,例如,print_result(f,1)我得到一个编译错误(编译器不知道f我的意思).我可以用print_result(f<int>,1)它来告诉它使用b),但是如何告诉它使用a)?
我发现我可以使用print_result(static_cast<int (*)(int)>(f), 1),但这感觉很乱,而且很麻烦.有没有更好的办法?
请考虑以下代码:
template<typename Derived>
struct Base {
static constexpr int x_base = Derived::x_derived;
//static_assert(x_base > 1, "Oops");
};
struct Derived : public Base<Derived> {
static constexpr int x_derived = 5 ;
};
Base<Derived> obj;
Run Code Online (Sandbox Code Playgroud)
这在gcc上编译很好,但如果我取消注释该static_assert行,它会抱怨
error: incomplete type 'Derived' used in nested name specifier
static constexpr int x_base = Derived::x_derived;
Run Code Online (Sandbox Code Playgroud)
我从4.9到5.3的不同版本的gcc试了一下,我也得到了同样的错误(你可以尝试在godbolt 这里).即使没有static_assert,clang也拒绝编译它,并抱怨
error: no member named 'x_derived' in 'Derived'
static constexpr int x_base = Derived::x_derived;
Run Code Online (Sandbox Code Playgroud)
哪个编译器是正确的(如果有的话)?有没有一种很好的方法来修复代码?
C++11范围内的枚举很棒,你应该尽可能使用它们.但是,有时您需要将整数转换为作用域枚举值(例如,如果您是从用户输入获取它).
有没有一种安全的方法来执行此操作并检测值何时无效(即,在枚举的允许值之外)?
我相信如果整数无效,只使用static_cast会导致未定义的行为.是否存在一种通用的方法,不需要手动为每个作用域枚举类型编写转换函数(每次向枚举添加新值时都需要更新)?
如果我的理解是正确的,CPython对象将在其引用计数达到零时立即删除.如果您的参考周期变得无法访问逻辑将无法工作,但有时解释器将尝试找到并删除它们(您可以通过调用gc.collect()手动执行此操作).
我的问题是,这些解释器触发的循环收集步骤何时发生?什么样的事件会引发他们?
我对CPython案例更感兴趣,但是很想知道PyPy或其他python实现的不同之处.