引用限定成员函数的股票示例似乎是这样的:
#include <stdio.h>
#include <stdexcept>
#include <string>
// Easy access to literals
using namespace std::literals;
// File wrapper
class File {
private:
// The wrapped file
FILE *_file;
public:
File(const char *name) :
_file(fopen(name, "r")) {
// unable to open the file?
if (!_file) throw std::runtime_error{ "Unable to open file: "s + name };
}
~File() {
fclose(_file);
}
// Convert to the underlying wrapped file
operator FILE *() & {
return _file;
}
// TODO: Member functions for working with the file
};
这很好用。无法直接从未命名的临时文件中检索底层 FILE 指针。但是,如果我们使强制转换运算符也具有 const 限定,这似乎不再有效。
即使这是一个非常有用的想法,不同的编译器也会毫无怨言地接受它。以 std::string::c_str() 成员函数为例。你觉得它应该是引用限定的(因为否则你有一个无效的指针)但它不是。
这是 C++11 标准中的一个漏洞吗?我在这里遗漏了什么吗?
最佳答案
临时对象可以绑定(bind)到 const&
限定对象,并且 ref 限定符有效限定隐式传递的对象 (*this
)。如果您想阻止对临时对象的调用但允许左值,您可以= delete
右值引用重载并实现左值版本。对两个运算符使用 const
限定的引用限定符只需要一个实现和一个 = delete
d 实现:
class File {
// ...
FILE* _file;
public:
operator FILE*() const&& = delete;
operator FILE*() const& { return this->_file; }
// ...
};
最终的结果是您只能将转换用于您转到左值的对象:
int main() {
File f;
File const cf{};
FILE* fp = f; // OK
FILE* cfp = cf; // OK
FILE* tfp = File(); // ERROR: conversion is deleted
FILE* mfp = std::move(cf); // ERROR: conversion is deleted
}
关于c++ - const-reference 限定成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33941020/