假设我有
class A final {
int& ir;
public:
A(int& x) : ir(x) { }
void set(int y) { ir = y; } // non-const method!
int get() const { return ir; }
};
和
const int i;
显然我不能拥有
A a(i);
因为这会打破常数。但我也不能拥有
const A a(i);
尽管事实上这不会破坏常态。 C ++不支持“const-only”ctors,例如在这种情况下,将采用const int&
。有没有办法让const A a
包含对i
的引用 - 除了
A a(const_cast<int &>(i))
答案 0 :(得分:4)
“Const”表示在构造函数结束和析构函数开始之间,对象是常量(在构造期间,您必须能够更改对象)。 C ++没有对const对象首选的“准备构造函数”。
您可以通过应用boost::variant
来尝试此解决方法。这在编译时不是完全类型安全的,但至少在抛出异常时在运行时检测错误。
#include <boost/variant.hpp>
#include <iostream>
class R {
boost::variant<int&, const int&> v;
public:
R(int&v):v(v) { }
R(const int&v):v(v) { }
// works with both
int get() const {
return boost::apply_visitor(
[](int x){return x;}, v);
}
// only works for non-const A. If at construction, a const
// int was passed, throws an error at runtime
void set(int x) {
boost::get<int&>(v) = x;
}
};
int main() {
int a = 0;
const int b = a;
R r1(a);
R r2(b);
const R r3(a);
std::cout << r1.get() << r2.get() << r3.get();
// r3.set(1); // compile error
r1.set(1); // works
r2.set(1); // runtime error
}
答案 1 :(得分:3)
C ++没有完全常量类的概念,如果引用int &
仅用作const int &
,则编译器可能无法执行。所以基本上,你不能这样做。
答案 2 :(得分:1)
很奇怪但是
class A final {
union{
int& ir;
const int ○
};
public:
A(int& x) : ir(x) { }
A(const int& x) : cir(x) { }
void set(int y) { ir = y; } // non-const method!
int get() const { return ir; }
};
int main(int argc, char *argv[])
{
const int cv = 8;
int v = 6;
A a( cv );
std::cout << a.get() << std::endl;
a.set( v );
std::cout << a.get() << std::endl;
return 0;
}
此外,你的set和get方法在值上操作而不是引用,所以它看起来像你做错了什么
答案 3 :(得分:1)
这不是我如何编写代码但它以某种方式工作。 如果从const变量构造模板类,则set()函数也定义为const,并且不会更改状态。通过从非const变量构造,set函数能够改变状态。
#include <iostream>
#include <string>
#include <type_traits>
template<typename T>
class A
{
T &_i;
public:
A(T &i) : _i(i) {}
template <typename D = T,
typename = std::enable_if_t<std::is_const<D>::value
>
>
void set(T i) const { std::cout << "Do nothing on set" << std::endl; }
template <typename D = T,
typename = std::enable_if_t<!std::is_const<D>::value>
>
void set(T i) { std::cout << "Do something on set" << std::endl; }
};
int main()
{
{
std::cout << "Construct from NON const variable" << std::endl;
int b = 5;
A<decltype(b)> a(b);
a.set(3);
}
{
std::cout << "Construct from const variable" << std::endl;
int const b = 5;
A<decltype(b)> a(b);
a.set(3);
}
}
打印:
Construct from NON const variable
Do something on set
Construct from const variable
Do nothing on set
答案 4 :(得分:0)
class A {
const int& ir; // <<-- it's a const int.
/* ... */
public:
A(int& x) : ir(x) { }
};