سؤال

ما هو الفرق بين

(type)value

و

type(value)

وفي C ++؟

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

المحلول

وليس هناك فرق. في المعيار (§5.2.3):

<اقتباس فقرة> A-نوع بسيط محدد (7.1.5) تليها قوسين التعبير عن قائمة يبني قيمة من النوع المحدد نظرا لقائمة التعبير. إذا كانت قائمة التعبير هو تعبير واحد، والتعبير عن نوع تحويل ما يعادل (في definedness، وإذا تم تعريفها في المعنى) إلى التعبير يلقي المقابلة (5.4).

وحيث أن قضية تحديد الفرق بين type(value) و(type)value، ليست هناك اي فرق.

إذا وفقط إذا كنت تتعامل مع قائمة مفصولة بفواصل من القيم يمكن أن يكون هناك اختلاف. في هذه الحالة:

<اقتباس فقرة> إذا تحدد قائمة التعبير أكثر من قيمة واحدة، يجب أن يكون نوع فئة مع منشئ أعلن مناسب (8.5، 12.1)، والتعبير T (X1، X2، ...) ما يعادل في الواقع إلى إعلان T ر (X1، X2، ...)؛ بالنسبة لبعض اخترع ر متغير مؤقت، ونتيجة لكونها قيمة ر باعتبارها rvalue.

وكما أشار الشاعر المتجول خارج، وهناك أسماء معينة من أنواع التي النسخة type(value) ببساطة لن تجميع. على سبيل المثال:

char *a = (char *)string;

وسيتم ترجمة، ولكن:

char *a = char *(string);

ولن. نفس النوع مع اسم مختلف (على سبيل المثال، تم إنشاؤها باستخدام typedef) يمكن أن تعمل على الرغم من:

typedef char *char_ptr;

char *a = char_ptr(string);

نصائح أخرى

وليس هناك فرق. وC ++ القياسية (1998 و 2003 طبعات) واضح حول هذه النقطة. جرب البرنامج التالي، تأكد من استخدام مترجم هذا المتوافقة، مثل معاينة مجانية في http://comeaucomputing.com/ tryitout / .

#include <cstdlib>
#include <string>
int main() {
  int('A'); (int) 'A'; // obvious
  (std::string) "abc"; // not so obvious
  unsigned(a_var) = 3; // see note below
  (long const&) a_var; // const or refs, which T(v) can't do
  return EXIT_SUCCESS;
}

ملحوظة: unsigned(a_var) هو مختلف، ولكن لا تظهر طريقة واحدة يمكن لهذه الرموز بالضبط يعني شيئا آخر. ومن إعلان متغير المسمى a_var من نوع غير موقعة، وليس الزهر على الإطلاق. (إذا كنت على دراية مع مؤشرات إلى وظائف أو المصفوفات، النظر في كيفية أن يكون لديك لاستخدام أقواس حول p في نوع مثل void (*pf)() أو int (*pa)[42]).

(ويتم إنتاج تحذيرات منذ هذه البيانات لا تستخدم قيمة وفي برنامج الحقيقي الذي كنت قد يكون من شبه المؤكد خطأ، ولكن كل شيء لا يزال يعمل. أنا فقط لم يكن لديك قلب لتغييره بعد إجراء خط كل شيء تصل).

وليس هناك فرق عندما كلاهما يلقي، لكن في بعض الأحيان 'نوع (القيمة)' ليس المدلى بها.

وهنا مثال من مشروع معيار N3242، القسم 8.2.1:

struct S 
{
    S(int);
};

void foo(double a) 
{
    S w( int(a) ); // function declaration
    S y( (int)a ); // object declaration
}

في هذه الحالة "كثافة العمليات (أ) 'ليس المدلى بها ل' ا 'ليست قيمة، بل هو اسم المعلمة تحيط بها أقواس زائدة عن الحاجة. وتنص الوثيقة

<اقتباس فقرة>   

والغموض الناشئة عن التشابه بين على غرار وظيفة   المدلى بها ويمكن أيضا أن تحدث في الإعلان المذكور في 6.8 في سياق   إعلان. في هذا السياق، والخيار بين وظيفة   إعلان مع مجموعة زائدة من أقواس حول معلمة   اسم وإعلان الكائن مع مجموعة من الممثلين على غرار وظيفة مثل   مهيئ. تماما كما لالغموض المذكورة في 6.8، و   القرار هو للنظر في أي بناء التي يمكن أن تكون   إعلان إعلان.

في ج لا يوجد type (value)، في حين ج ++ يسمح في ج / كلا type (value) و(type) value.

لتوضيح خياراتك في C ++ (واحد فقط لديه فحص السلامة)

#include<boost/numeric/conversion/cast.hpp> 

using std::cout;
using std::endl;
int main(){

    float smallf = 100.1;

    cout << (int)smallf << endl; // outputs 100 // c cast
    cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast

    cout << static_cast<int>(smallf) << endl; // outputs 100
//  cout << static_cast<int&>(smallf) << endl; // not allowed
    cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563
    cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100

    float bigf = 1.23e12;

    cout << (int)bigf << endl; // outputs -2147483648
    cout << int(bigf) << endl; // outputs -2147483648

    cout << static_cast<int>(bigf) << endl; // outputs -2147483648
//  cout << static_cast<int&>(bigf) << endl; // not allowed
    cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083
    cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top