const_ast في القالب. هل هناك تعديل غير مركزي؟
-
19-09-2019 - |
سؤال
لدي فئة قالب مثل هذا:
template<T>
class MyClass
{
T* data;
}
أحيانا، أريد استخدام الفصل مع نوع ثابت باسم T كما يلي:
MyClass<const MyObject> mci;
ولكن أريد تعديل البيانات باستخدام const_cast<MyObject*>data
(ليس من المهم لماذا ولكن MyClass
هو رقم مرجعي رقم مؤشر ذكي يحتفظ بعدد المرجع في البيانات نفسها. MyObject
مشتق من نوع ما يحتوي على عدد. لا ينبغي تعديل البيانات ولكن يجب تعديل العدد من قبل المؤشر الذكي.).
هل هناك طريقة لإزالة const-ness من T
ب الرمز الخيالي:
const_cast<unconst T>(data)
?
المحلول
أبسط طريقة هنا ستكون لجعل العد المرجعي قابل للتغيير.
ومع ذلك، إذا كنت مهتما بكيفية العمل مع const_cast
, ، ثم إعادة تشغيل دفعة remove_const
يجب أن تكون بسيطة للغاية:
template <class T>
struct RemoveConst
{
typedef T type;
};
template <class T>
struct RemoveConst<const T>
{
typedef T type;
};
const_cast<typename RemoveConst<T>::type*>(t)->inc();
نصائح أخرى
لديك الجواب. يعمل const_ast في كلا الاتجاهين:
char* a;
const char* b;
a = const_cast<char*>(b);
b = const_cast<const char*>(a); // not strictly necessarily, just here for illustration
أما بالنسبة لك مسألة محددة، فهل اعتبرت كلمة رئيسية قابلة للتغيير؟ يسمح بتعديل متغير العضو داخل طريقة CONST.
class foo {
mutable int x;
public:
inc_when_const() const { ++x; }
dec_when_const() const { --x; }
};
اجعل العد المرجعي قابل للتغيير في الفصل يديره مؤشر تدفئة. هذا معقول تماما، وتعكس "النسيان المنطقي" بشكل صحيح تماما - أي تغيير عدد مرجعي الكائن لا يعكس أي تغيير في حالة الكائن نفسه. بمعنى آخر، فإن عدد المرجع غير مناسب منطقيا من الكائن - الكائن يحدث فقط أن يكون مكانا ملائما لتخزين البيانات شبه غير ذات الصلة.
إذا كنت تستطيع استخدام دفعة، فإن مكتبة الصفات من النوع توفر Remove_Const. metafunction هذا يفعل ذلك.
هنا هو بلدي C ++ 11 unconst
وظيفة template
.
إذا كنت تستخدمه، فأنت تغازل السلوك غير محدد. وبعد لقد كنت حذر.
// on Ubuntu (and probably others) compile and test with
// g++ -std=c++11 test.c && ./a.out ; echo $?
template < class T > T & unconst ( T const & t ) {
return const_cast < T & > ( t ) ;
}
// demonstration of use
struct {
const int n = 4;
} s;
int main () {
unconst ( s.n ) = 5;
return s.n;
}