C ++ التحويلات الضمنية والغموض في استدعاء الوظائف الزائدة

StackOverflow https://stackoverflow.com/questions/3112602

سؤال

أواجه المشكلة التالية: لدي فئة V (على سبيل المثال متجه) يمكنني من خلاله إنتاج فئتين: CI و I (فكر في const_iterator و iterator). إذا كان لديّ const v ، فلا يمكنني سوى إنتاج CI (مرة أخرى فكر في Iterator و const_iterator).

في الأساس أود أن أقدم (const v & v) مع (ci ci) و (v & v) مع (i i). علاوة على ذلك ، أود أن أكون قادرًا على تمرير V obj مباشرة إلى وظائف تتوقع i أو ci وبالتالي التحويلات الضمنية من V و const v إلى CI و I.

المشكلة التي أواجهها هي أنه على الرغم من أن الوظائف المحملة الزائدة يمكن أن تميز بين (const v & v) و (v & v) ، فإنها لا تستطيع "التمييز" بين (ci ci) و (i i) عندما أقوم بتمرير V obj.

في الكود:

struct V {};

struct I 
{
    I( V& v ){}
};

struct CI
{
    CI( const V& v ){} //I would like to say const only 
};

void fun( I i )
{
    double x = 1.0;
}
void fun( CI ci )
{
    double x = 2.0;
}

void fun2( V& v )
{
    double x = 1.0;
}
void fun2( const V& v )
{
    double x = 2.0;
}

لاحظ أنه كان بإمكاني تحديد مشغل التحويلات في V (هل هو مكافئ؟) بدلاً من تحديد المُنشئين في CI و I. الآن:

V v;
const V cv;

fun2( v );
fun2( cv );

fun( v ); //AMBIGUOUS!
fun( cv );

هل هناك طريقة لحل هذه المشكلة دون إضافة أي توجيه إضافي (أي لا يمكن تعديل وظائف المرح ويجب تمرير V مباشرة إلى المرح ولكنك حر في تعديل كل شيء آخر).

شكرا لكم مقدما على أي مساعدة!

هل كانت مفيدة؟

المحلول

ما تحتاجه هنا هو منشئات صريحة:

struct I 
{
    explicit I( V& v ){}
};

struct CI
{
    explicit CI( const V& v ){} //I would like to say const only 
};

يتجاهل الكثير من مبرمجي C ++ الكلمة الرئيسية الصريحة للمشاركين. يجب أن تكون جميع البنائين أحادية المعلمة واضحة بشكل افتراضي. يدعو المنشئون الضمنيون مشاكل الغموض مثل هذه وكذلك يؤدي إلى عمليات تحويل الدوار الشديدة التي يمكن أن تؤدي بسهولة إلى رمز إشكالي وغير فعال للغاية.

أنت الآن ضبط ، حل مشكلة الغموض. بدون منشئات صريحة ، لا يمكنك منع مشكلة الغموض هذه.

بالنسبة لرمز العميل ، تحتاج إلى تعديله ليكون صريحًا حول تحويلاته:

V v;
const V cv;

fun2( I(v) );
fun2( CI(cv) );

fun( I(v) );
fun( CI(cv) );

سيُطلب من مثل هذا الجملة الآن إنشاء كائنات من I أو CI ، ولكن هذا شيء جيد: لا يمكن لأحد أن يقدم مشاكل الغموض بطريق الخطأ.

نصائح أخرى

ماذا عن مجرد استخدام typedefس؟

typedef V& I;
typedef const V& CI;

يحرر:

رقم انظر التعليقات :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top