سؤال

وأنا أكتب بعض التعليمات البرمجية نقطة بسيطة بينما كان يحاول الخروج البصرية ستوديو 10 (بيتا 2)، ولقد ضرب هذا الرمز حيث أتوقع SFINAE لركلة في، ولكن على ما يبدو ليس ل:

template<typename T>
struct point {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

template<typename T, typename U>
struct op_div {
    typedef decltype(T() / U()) type;
};

template<typename T, typename U>
point<typename op_div<T, U>::type>
operator/(point<T> const& l, point<U> const& r) {
    return point<typename op_div<T, U>::type>(l.x / r.x, l.y / r.y);
}

template<typename T, typename U>
point<typename op_div<T, U>::type>
operator/(point<T> const& l, U const& r) {
    return point<typename op_div<T, U>::type>(l.x / r, l.y / r);
}

int main() {
    point<int>(0, 1) / point<float>(2, 3);
}

وهذا يعطي error C2512: 'point<T>::point' : no appropriate default constructor available

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

في هذه الحالة بعض الحلول هي ببساطة مضمنة في decltype(T() / U())، لإعطاء الطبقة نقطة منشئ افتراضي، أو لاستخدام decltype على التعبير نتيجة الكامل، ولكن حصلت على هذا الخطأ بينما كان يحاول تبسيط خطأ كنت الحصول على مع نسخة من op_div التي لا تتطلب منشئ افتراضي *، لذلك أود أن بدلا من إصلاح فهمي C ++ بدلا من مجرد تفعل ما يعمل.

وشكرا!


*: النص الأصلي:

template<typename T, typename U>
struct op_div {
    static T t(); static U u();
    typedef decltype(t() / u()) type;
};

والذي يعطي error C2784: 'point<op_div<T,U>::type> operator /(const point<T> &,const U &)' : could not deduce template argument for 'const point<T> &' from 'int'، وأيضا من أجل الزائد point<T> / point<U>.

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

المحلول

وليس متأكدا 100٪. ويبدو أن المترجم يحتاج إلى مثيل على حد سواء الزائدة لتحديد أيهما أفضل، ولكن بينما كان يحاول مثيل op_div البعض مع T = int وU = point<float>، وهذا يؤدي إلى الخطأ التي لا تغطيها SFINAE (الخطأ ليس أن op_div لا لدينا نوع في هذه الحالة، ولكن لا يمكن تحديد هذا النوع).

هل يمكن أن محاولة تعطيل الزائد الثاني إذا كان النوع الثاني هو نقطة (boost::disable_if).

وأيضا، ما يبدو تم تأجيل إعلان نوع الإرجاع للعمل (التخلص من البنية op_div، ولكن اعتمادا على أي معتمدة C ++ 0X الميزات من قبل المترجم الخاص بك):

template<typename T, typename U>
auto
operator/(point<T> const& l, point<U> const& r) -> point<decltype(l.x / r.x)> {
    return {l.x / r.x, l.y / r.y};
}

template<typename T, typename U>
auto
operator/(point<T> const& l, U const& r) -> point<decltype(l.x / r)> {
    return {l.x / r, l.y / r};
}

نصائح أخرى

وأود أن أقول خطأ الخاص بك هو في هنا:

template<typename T>
struct point {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

وتغيير تعريف البنية لهذا:

template<typename T>
struct point<T> {
    T x, y;
    point(T x, T y) : x(x), y(y) {}
};

إذا كنت ترغب في استخدام عام نوع T، تحتاج إلى تحديد ذلك في التعريف.

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