سؤال

بعد قراءة واسعة من ISO/IEC 14882, لغة البرمجة C++ أنا لا تزال غير متأكد لماذا const مطلوب التحويل الضمني إلى نوع معرف من قبل المستخدم مع منشئ حجة واحدة كما يلي

#include <iostream>

class X {
public:
   X( int value ) {
      printf("constructor initialized with %i",value);
   }
}

void implicit_conversion_func( const X& value ) {
   //produces "constructor initialized with 99"
}

int main (int argc, char * const argv[]) {
   implicit_conversion_func(99);
}



بدءا من القسم 4 خط 3

تعبير e يمكن أن يكون ضمنيا تحويلها إلى نوع T إذا و فقط إذا كان الإعلان T t=e ؛ وكذلك شكلت بعض اخترع متغير مؤقت t (8.5).بعض بنيات اللغة تتطلب أن تعبير يمكن تحويلها إلى قيمة منطقية.تعبير ه الظهور في هذا السياق هو أن يكون السياق تحويلها إلى منطقي و هو جيد إذا و فقط إذا كان الإعلان منطقي t(هـ) ؛ وكذلك شكلت بعض اخترع متغير مؤقت t (8.5).تأثير إما التحويل الضمني هو نفس أداء الإعلان التهيئة ثم باستخدام متغير مؤقت نتيجة التحويل.والنتيجة هي lvalue إذا ر هو lvalue نوع مرجع (8.3.2) ، rvalue خلاف ذلك.التعبير e يستخدم كمادة lvalue إذا وفقط إذا كانت التهيئة يستخدم على أنها lvalue.

بعد أن وجدت القسم على المهيآت المتعلقة الأنواع المعرفة من قبل المستخدم في 8.5 خط 6

إذا كان البرنامج يستدعي الافتراضي تهيئة كائن من const-مؤهل نوع T, T يجب أن تكون الطبقة مع المستخدم المقدمة منشئ افتراضي.

وأخيرا انتهى بي الأمر في 12.3 خط 2 عن المعرفة من قبل المستخدم التحويلات التي تنص على

تحويلات المعرفة من قبل المستخدم يتم تطبيقها فقط حيث هم لا لبس فيه (10.2, 12.3.2).

وغني عن القول 10.2 و 12.3.2 لم تجب على سؤالي.

  1. شخص ما يمكن أن يلقي بعض الضوء على ما تأثير const وقد ضمني على التحويلات ؟
  2. هل استخدام const إجراء عملية التحويل "لا لبس فيه" في 12.3 خط 2?
  3. لا const تؤثر بطريقة أو بأخرى lvalue مقابلrvalue تحدثت عنها في القسم 4?
هل كانت مفيدة؟

المحلول

ليس لديها الكثير لتفعله مع تحويل يجري ضمني.وعلاوة على ذلك, ليس لديها الكثير لتفعله مع التحويلات.هو حقا عن rvalues مقابل lvalues.

عند تحويل 99 إلى نوع X, النتيجة هي rvalue.في C++ نتائج التحويلات دائما rvalues (إلا إذا كنت تحويل إلى نوع مرجع).أنه من غير القانوني في C++ إرفاق غير const إشارات إلى rvalues.

على سبيل المثال هذا الكود وليس تجميع

X& r = X(99); // ERROR

لأنه يحاول إرفاق غير const إشارة إلى rvalue.من ناحية أخرى, هذا هو رمز بخير

const X& cr = X(99); // OK

لأنه هو تماما موافق إلى إرفاق const إشارة إلى rvalue.

نفس الشيء يحدث في التعليمات البرمجية الخاصة بك كذلك.حقيقة أنه ينطوي ضمنيا تحويل نوعا ما بجانب نقطة.يمكنك استبدال التحويل الضمني مع صريح واحد

implicit_conversion_func(X(99));

و في نهاية المطاف مع نفس الوضع:مع const وهي تجمع دون const لا.

مرة أخرى, إلا دور التحويل (صريحة أو ضمنية) يلعب هنا هو أنه يساعدنا على إنتاج rvalue.في عام ، يمكن أن تنتج rvalue في بعض طريقة أخرى واجهت نفس المشكلة

int &ir = 3 + 2; // ERROR
const int &cir = 3 + 2; // OK

نصائح أخرى

لكل القسم 5.2.2 الفقرة 5 ، عندما تكون الوسيطة إلى وظيفة ما const النوع المرجعي ، يتم تقديم متغير مؤقت تلقائيًا إذا لزم الأمر. في مثالك ، نتيجة RVALUE لـ X(99) يجب وضعه في متغير مؤقت بحيث يمكن تمرير هذا المتغير const إشارة إلى implicit_conversion_func.

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