إلى الأمام بإعلان وظيفة تستخدمها Enable_IF: مكالمة غامضة
-
19-09-2019 - |
سؤال
لدي بعض المشاكل في إعادة توجيه وظيفة تستخدم boost::enable_if
: قطعة التعليمية التالية تعطيني خطأ مترجم:
// Declaration
template <typename T>
void foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
int main()
{
foo(12);
return 0;
}
عند تجميع الأخطاء، أحصل على خطأ "مكالمة غامضة إلى FOO". وفقا لتعريف enable_if
, ، يتوافق Typedef "النوع" void
عندما تكون الحالة صحيحة، حتى الآن كما أستطيع أن أرى، التوقيعان foo
تطابق. لماذا يعتقد المترجم أنهم مختلفون، وهناك طريقة صحيحة لإعادة توجيه الاعلانات foo
(يفضل دون تكرار enable_if
جزء)؟
المحلول
هذه ليست مشكلة فقط مع Enable_If. تحصل على نفس الخطأ على Visual Studio و GCC مع التعليمات البرمجية التالية:
struct TypeVoid {
typedef void type;
};
template<typename T>
void f();
template<typename T>
typename T::type f() {
}
int main()
{
f<TypeVoid>();
return 0;
}
أعتقد أن المشكلة الرئيسية هي أن نوع الإرجاع (قبل إنشاء مثيل) هو جزء من توقيع وظيفة القالب. هناك مزيد من المعلومات هنا.
فيما يتعلق بالكود الخاص بك، إذا كان الإعلان يشير إلى التعريف، فيجب عليك مطابقة كليهما:
// Declaration
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
إذا كان الإعلان يشير إلى وظيفة مختلفة، فلن يتمكن التحويل البرمجي أبدا من اختيار واحد الصحيح ل إتجاهS، لأن كلاهما صالحين. ومع ذلك، يمكنك تعطيل أول واحد ل إتجاهS باستخدام تعطيل_IF.:
// Other function declaration
template <typename T>
typename boost::disable_if<boost::is_same<T, int> >::type foo(T t);
// Defition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
نصائح أخرى
المشكلة هي أن الإعلان والتعريف لا يتطابقان.
الحل هو أن الإعلان يجب أن يحتوي على نفس التوقيع بالضبط، و enable_if
قليل.
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
// Declaration
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t);
// Definition
template <typename T>
typename boost::enable_if<boost::is_same<T, int> >::type foo(T t)
{
}
int main()
{
foo(12);
return 0;
}
هذا يجمع بشكل جيد على VC2008.