c++ محمد - هل بنية النموذج هذه غير قانونية؟




العلي معلقني (2)

template <typename T, typename, int, template <typename U, U, U> class>
  struct Sort;  

هذا قانوني تمامًا.

يمكن أن يتم الإعلان عنه من هذا القبيل ، مع إعطاء أسماء لجميع المعلمات:

template <typename T, typename T2, int I, template <typename U, U X, U Y> class TT>
  struct Sort;  

يعلن عن قالب فئة Sort الذي يحتوي على أربعة معلمات قالب ، معلمة النوع T ، معلمة نوع ثاني T2 (غير مسماة في الأصل) ، معلمة قالب غير من النوع I ، ومعلمة قالب قالب TT .

يجب أن يكون TT قالب معلمة قالب قالب أخذ معلمات قالب ثلاثة، U معلمة نوع و الثاني و الثالث ( X و Y ) معلمات قالب غير نوع من نوع U

قد تكون الوسيطة المناسبة لمعلمة القالب الرابعة من Sort مثل:

template <typename T, T t1, T t2>
  class Foo
  { static const bool value = t1 < t2; };

والتي سيتم إنشاء مثيل مثل:

Foo<int, 1, 2> fi;

أو

Foo<char, 'a', 'b'> fc;

أحصل على "خطأ داخلي في التحويل البرمجي" مع هذا باستخدام GCC 4.9.2:

#include <type_traits>

template <typename T, typename, int, template <typename U, U, U> class>
struct Sort;

template <typename T, template <T...> class Z, T N, T... Is,
          template <typename U, U, U> class Comparator>
struct Sort<T, Z<N, Is...>, 0, Comparator> {
  template <T I>
  struct less_than : std::integral_constant<bool, Comparator<T, I, N>::value> {
  };
};

int main() {}

حالات رسالة الخطأ:

c: \ ADandD> g ++ -std = c ++ 14 ComparatorAndSorterTGeneralized.cpp ComparatorAndSorterTGeneralized.cpp: 254: 80: خطأ المحول البرمجي الداخلي: في tsubst ، عند cp / pt.c: 11738

template<T I>
struct less_than : std::integral_constant<bool, Comparator<T,I,N>::value> {};
                                                                              ^

يرجى إرسال تقرير خطأ كامل ، مع مصدر مُعالج مسبقًا إذا كان ذلك مناسبًا. انظر http://gcc.gnu.org/bugs.html للحصول على التعليمات.

المشكلة هي القالب <typename U, U, U> class Comparator قيد الاستخدام. لم أحاول هذا من قبل في البداية جربت القالب <typename T, T, T> class Comparator ، لكن ذلك لن <typename T, T, T> class Comparator بسبب تظليل القالب ، لذلك كنت أعرف أن ذلك غير قانوني. ثم تغييره إلى U لا يزال لا تجميع ، لذلك أعتقد أن الفكرة كلها غير مسموح بها.

تحديث: عند instantiating ، هذا compile في Visual Studio 2015 معاينة:

#include <type_traits>

template <typename T, typename, int, template <typename U, U, U> class>
struct Sort;

template <typename T, template <T...> class Z, T N, T... Is,
          template <typename U, U, U> class Comparator>
struct Sort<T, Z<N, Is...>, 0, Comparator> {
  template <T I>
  struct less_than : std::integral_constant<bool, Comparator<T, I, N>::value> {
  };
};

template <int...>
struct index_sequence {};

template <typename T, T A, T B>
    struct LessThan : std::integral_constant < bool,
    A<B> {};

enum { QuickSort, MergeSort, InsertionSort };

int main() {
  Sort<int, index_sequence<4, 5, 6, 1, 2, 7>, QuickSort, LessThan> quickSort;
}

أفضل من do {} while (0) if (1) {} else ، يمكن للمرء ببساطة استخدام ({}) :

#define FOO(X) ({f(X); g(X);})

وهذا البناء متوافق مع قيم الإرجاع ( do {} while (0) لا) ، كما في:

return FOO("X");




c++ templates