在初始化表达式中强制左值的const-ness
C++ Force const-ness of lvalue in initializer expression
我希望编译器强制左值(非引用)的const-ness,但不知道这在c++中是否可能。一个例子:
int foo() { return 5; }
int main() {
// Is there anything I can add to the declaration of foo()
// that would make the following cause a compile-error?
int a = foo();
// Whereas this compiles fine.
const int a = foo();
}
对于像int
这样的对象来说,这是不可能的,因为你需要允许读取int型,如果他们可以读取int型,那么他们可以将其复制到非const int型。
但是从你的评论中听起来,你在现实中拥有的不是int
,而是更复杂的用户定义类型,某种容器。您可以轻松地创建不可变容器。该容器可以是包装器,也可以是现有容器的替代实现。无论调用者使用const还是非const变量,它仍然是不可变的。
class MyClass {
std::vector<int> data;
public:
MyClass(size_t size) : data(size) {}
int& operator[](size_t index) { return data[index]; }
int operator[](size_t index) const { return data[index]; }
size_t size() const { return data.size(); }
};
class MyClassImmutable {
MyClass mc;
public:
MyClassImmutable(MyClass&& mc) : mc(std::move(mc)){}
int operator[](size_t index) const { return mc[index]; }
size_t size() const { return mc.size(); }
const MyClass& get() const { return mc; }
};
MyClassImmutable foo() {
MyClass mc(100);
mc[10] = 3;
return mc;
}
void func(const MyClass& mc);
int main() {
MyClassImmutable mci = foo();
std::cout << mci[10] << "n"; // Can read individual values
//mci[10] = 4; // Error immutable
func(mc.get()); // call function taking a const MyClass&
}
现场演示。
当然,没有什么可以阻止调用者从不可变容器中复制每个值并将它们插入到可变容器中。
Edit:另一种方法可能是返回指向const的智能指针。唯一的缺点是您必须为动态内存分配付费:
std::unique_ptr<const MyClass> foo() {
auto mc = std::make_unique<MyClass>(100);
(*mc)[10] = 3;
return mc;
}
void func(const MyClass& mc);
int main() {
auto mc = foo();
std::cout << (*mc)[10] << "n"; // Can read individual values
//(*mc)[10] = 4; // Error const
func(*mc); // can pass to a function taking a const MyClass&
}
不可能。foo()
无法知道左侧赋值的类型,因为当赋值发生时,foo()
已经被求值了。最好的情况是更改返回值,尝试在初始化时导致基于类型的错误:
#include <type_traits>
struct my_int {
const int m;
template<typename T, typename std::enable_if<std::is_const<T>::value, T>::type* = nullptr>
constexpr operator T() const {return m;}
};
constexpr my_int foo() { return {5};}
int main() {
const int a = foo();
int b = foo();
}
生活例子
但是这也行不通,因为模板中的typename永远不会被const限定类型所替换(在本例中,main()
中的两行都是int
)。
如下所示
const int x = 4;
int y = x;
c++语言不会提供这样的机制。
通过宏机制保持int const。
#define int_const_foo(var) const int var = ___foo()
int_const_foo(a);
缺点:foo不能隐藏,语法也不再是C风格了
相关文章:
- 如何在旧c++中初始化const-std向量
- 初始化或分配空字符串文字到指向 C 中的 char 的指针或指向 C++ 中 const char 的指针的原因是什么
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- 为什么通过指针编译时不能分配 const 初始化
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 使用 const char* 初始化 const ref 字符串成员时幕后会发生什么
- 如何使用 C++ 中的原语初始化类(如 std::字符串从 const char* 初始化)
- 具有字符串文本构造函数的类不适用于 const 引用初始化
- 在这种情况下,如何从类型 "const char*" 初始化字段?
- 与其他静态const成员初始化静态常量成员
- 使用 C++ 中的自定义元素进行 Const 结构初始化
- const成员初始化之前的用法是GCC和Clang的这种预期行为
- 在同一构造函数中使用该 const int 初始化 const int 和对象
- 在 ctor 中使用 const&vector 初始化的 const&vector 成员
- 使用const指针初始化const结构
- 在初始化表达式中强制左值的const-ness
- 模板类中的静态const成员初始化
- 用const char初始化2D char数组元素
- 用函数初始化静态const的初始化顺序
- 如何用const值初始化const对象的非const属性