سؤال

هل هناك C++ أي ما يعادل C# null ائتلافه المشغل ؟ أنا أفعل الكثير من null يتحقق في قانون بلدي.إذا كنت تبحث عن وسيلة لتقليل كمية من التعليمات البرمجية فارغة.

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

المحلول

لا توجد طريقة للقيام بذلك افتراضيًا في C ++ ، ولكن يمكنك كتابة واحدة:

في C# ؟؟ يتم تعريف المشغل على أنه

a ?? b === (a != null ? a : b)

لذلك ، ستبدو طريقة C ++

Coalesce(a, b) // put your own types in, or make a template
{
    return a != null ? a : b;
}

نصائح أخرى

لقد وجدت هذا للتو: ال ؟؟ المشغل الملقب مشغل الفحم الفارغ

لديك أيضًا في C/C ++ كملحق GNU باستخدام ?:المشغل أو العامل :

string pageTitle = getTitle() ?: "Default Title";

باستخدام القوالب و C ++ 11 lambdas. يتم تقييم الحجة الأولى (الجانب الأيسر) مرة واحدة فقط. يتم تقييم الوسيطة الثانية (الجانب الأيمن) فقط إذا كانت الأولى خاطئة (لاحظ أنه "إذا" و "؟"؟ إلى '! = nullptr')

template<typename TValue, typename TSpareEvaluator>
TValue
coalesce(TValue mainValue, TSpareEvaluator evaluateSpare) {

    return mainValue ? mainValue : evaluateSpare();
}

مثال على الاستخدام

void * const      nonZeroPtr = reinterpret_cast<void *>(0xF);
void * const otherNonZeroPtr = reinterpret_cast<void *>(0xA);

std::cout << coalesce(nonZeroPtr, [&] () { std::cout << "Never called"; return otherNonZeroPtr; }) << "\n";

سوف طباعة "0xf" فقط في وحدة التحكم. الاضطرار إلى كتابة lambda ل RHS هو القليل من الغلاية

[&] () { return <rhs>; }

ولكن من الأفضل أن يفعل المرء إذا كان المرء يفتقر إلى الدعم من قبل بناء جملة اللغة.

وماذا عن هذا؟

#define IFNULL(a,b) ((a) == null ? (b) : (a))

فقط أرغب في توسيع إجابة Samuel Garcia من خلال تعميم القالب وإضافة وحدات الماكرو المساعد لخفض على Lambda Boilerplate:

#include <utility>

namespace coalesce_impl
{
    template<typename LHS, typename RHS>
    auto coalesce(LHS lhs, RHS rhs) ->
        typename std::remove_reference<decltype(lhs())>::type&&
    {
        auto&& initialValue = lhs();
        if (initialValue)
            return std::move(initialValue);
        else
            return std::move(rhs());
    }

    template<typename LHS, typename RHS, typename ...RHSs>
    auto coalesce(LHS lhs, RHS rhs, RHSs ...rhss) ->
        typename std::remove_reference<decltype(lhs())>::type&&
    {
        auto&& initialValue = lhs();
        if (initialValue)
            return std::move(initialValue);
        else
            return std::move(coalesce(rhs, rhss...));
    }
}

#define COALESCE(x) (::coalesce_impl::coalesce([&](){ return ( x ); }))
#define OR_ELSE     ); }, [&](){ return (

باستخدام وحدات الماكرو ، يمكنك فقط:

int* f();
int* g();
int* h();

int* x = COALESCE( f() OR_ELSE g() OR_ELSE h() );

آمل أن يساعد هذا.

هناك جنو دول مجلس التعاون الخليجي التمديد التي تسمح باستخدام ?: المشغل مع منتصف المعامل في عداد المفقودين ، انظر الشرطية مع حذف المعاملات.

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

ولذلك فإن التعبير

x ? : y

له قيمة x إذا كان هذا هو صفر غير ؛ وإلا قيمة y.

هذا المثال هو تماما ما يعادل

x ? x : y

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

هذا التمديد هو أيضا بدعم من رنة.ومع ذلك ، يجب أن تحقق مع المترجم كنت تستخدم وقابلية متطلبات الكود الخاص بك قبل استخدام هذا التمديد.لا سيما MSVC C++ compilers لا تدعم حذف المعاملات في ?:.

انظر أيضا ذات الصلة ستاكوفيرفلوو المناقشة هنا.

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