防止 C++14 中的 L 值实例化
Preventing L-value instantiation in C++14
C++14 中的方法可以判断它们是在 L 值还是 R 值上调用:
struct A{
A() { puts("Ctor"); }
void m() const & { puts("L-value"); }
void m() const && { puts("R-value"); }
};
int main(){
A a; //Ctor
a.m() //L-value
A().m(); //Ctor; R-value
}
CTOR 可以分辨出它正在构建哪种类型吗?我可以完全禁用类中 L 值的构造吗?
我有一个代理类(实际上是几个),它应该始终转换为其他东西。在不转换的情况下使用它是一个错误。我可以在运行时检测到该错误,例如,通过添加一个bool used_ = 0;
成员#ifndef NDEBUG;
并在我用户指定的强制转换中设置它,然后在代理类的Dtor
中执行assert(used_)
,但是如果我能得到编译器以防止首先L-value
代理实例的插入,那就更好了:
auto x = Proxy().method1().method2(); // no
Proxy p; // no
Target x = Proxy(); //yes
Target x = Proxy().method1().method2(); //yes
我可以用 C++14 做这样的事情吗?
struct temporary_only {
static temporary_only make() { return {}; }
temporary_only(temporary_only&&)=delete;
int get()&& { return 3; }
private:
temporary_only() {}
};
int main() {
//temporary_only x; // illegal
std::cout << temporary_only::make().get() << 'n'; // legal
}
活生生的例子。
我们禁用所有公共 ctor(包括复制/移动),因此除了通过 temporary_only::make
(右值)之外,没有人可以创建temporary_only
。
请注意,
temporary_only&& a = temporary_only::make();
仍然有效。 在这里,我们有一个绑定到右值引用的右值,并且该右值引用本身就是具有多行生存期(作用域生存期)的左值。 这是无法阻止的。
为什么,当然:
#include <iostream>
using namespace std;
class B;
class A
{
public:
A(B&& b) {}
A(const B&) = delete;
};
class B {};
int main()
{
B b;
// A a1; <- error
// A a2 = b; // <- error
A a3 = move(b); // <- fine
return 0;
}
相关文章:
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 为什么我们不在下面给出的代码中使用指针来实例化C++的实体对象?
- 我有一个类,它创建了另一个类的实例.如何将变量通过第一个类传递到第二个类的实例化中?
- OSX clang++:用于 cpp 文件中显式实例化模板的体系结构x86_64的未定义符号
- 您能否实例化模板的非专用版本并在专用化中继承它?
- 请参阅在 Visual Studio 2019 中捕获 std::exception 时对函数模板实例化消息的引用
- 类模板实例化中的类型转换
- 在 Xcode 中实例化后的显式专用化
- 模板类实例化中的指针转换无效
- 编译器之间在丢弃的 if constexpr(false) 语句中实例化模板的行为不一致
- C++部分模板实例化中的 typedef
- 显式使用类模板实例化中某些参数的默认值
- 在完全专用的模板函数中实例化类的对象
- 为什么在显式实例化中不适当地访问privates是合法的
- 可变参数模板实例化中的无限递归,试图构建任意深度的树状结构
- C++:在堆栈中实例化类的正确方法是什么
- 未在此作用域中声明实例化类/的作用域
- 我可以使用decltype()来避免显式模板实例化中的代码重复吗
- 为什么没有询问priority_queue实例化中比较器的模板参数
- 优雅地重用将const添加到类实例化中的代码