سؤال

أحاول استنتاج نوع الإرجاع للوظيفة واستخدامه كنوع الإرجاع لوظيفة العضو.لهذا أنا أستخدم تعبير decltype.لكن كل محاولاتي تفشل في التجميع إذا كانت الوظيفة المحددة تأخذ مرجعًا كوسيطة:

  • لا أستطيع استخدام أي متغيرات عضو من صفي في تعبير decltype، لأن المترجم يشكو من عدم وجود مثل هؤلاء الأعضاء (انظر func1 أقل)
  • لا يمكنني استخدام مؤقت لمعلمة الوظيفة، نظرًا لأن الوظيفة تأخذ مرجعًا ولا يمكنك ربط مرجع قيمة غير ثابت بمعلمة مؤقتة (راجع func2 أقل)

لقد جربت أيضًا العديد من عوامل الصب لجعل المرجع مؤقتًا، ولكن لا يبدو أن هناك تعبيرًا صالحًا.

هنا مثال على الكود:

template<typename data_type, typename functor_type>
class MyClass
{
public:
    auto func1() -> decltype(functor_type::process(this->m_data)) // <--
    {
        return functor_type::process(m_data);
    }

    auto func2() -> decltype(functor_type::process(data_type{})) // <--
    {
        return functor_type::process(m_data);
    }

private:
    data_type m_data;
};

struct Functor
{
    static int process(int& a) { return a; }
};

int main()
{
    MyClass<int, Functor> m;
    int b = m.func1();
    int c = m.func2();
}
هل كانت مفيدة؟

المحلول

فشل الأول لأن الفئة لم تكتمل في إعلان الوظيفة، كما هو الحال في الهيئات الوظيفية للأعضاء، لذلك يمكنك فقط استخدام الأعضاء الذين تم الإعلان عنهم بالفعل.

وللثانية، توفر المكتبة القياسية declval, ، تم الإعلان عن قالب دالة لإرجاع نوع معلمة القالب الخاص به.يمكنك استخدام هذا في سياقات غير مقيمة عندما تحتاج إلى تعبير من نوع معين.

لذلك يجب أن تعمل النسخة التالية:

#include <utility> // for declval

template<typename data_type, typename functor_type>
class MyClass
{
private:
    // Declare this before `func1`
    data_type m_data;

public:
    // Use the already declared member variable
    auto func1() -> decltype(functor_type::process(m_data))
    {
        return functor_type::process(m_data);
    }

    // Or use `declval` to get an expression with the required reference type
    auto func2() -> decltype(functor_type::process(std::declval<data_type&>()))
    {
        return functor_type::process(m_data);
    }
};    

نصائح أخرى

أعتقد أنك تبحث عنه std::declval<data_type&>()

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