Метапрограммирование C++ - генерация ошибок в коде

Я бы использовал precacheImage , чтобы загрузить изображения в pages один за другим, а когда прибыл, заменил URL в pages, чтобы вместо заполнителя отображалось реальное изображение. ]

for(final page in pages) {
  await precacheImage(page.downloadUrl, context);
  page.displayUrl = page.downloadUrl;
  setState(() => pages = pages.toList();
}

6
задан Peter Mortensen 7 February 2010 в 13:52
поделиться

4 ответа

Если Вы не хотите Повышение волшебство Библиотек C++ и хотите скелет...

template<bool> class static_check
{
};

template<> class static_check<false>
{
private: static_check();
};

#define StaticAssert(test) static_check<(test) != 0>()

Затем используйте StaticAssert. Это - #define для меня, потому что у меня есть код, который должен работать в большом количестве сред, где C++ не работает правильно для шаблонов, и я должен просто отступить, это ко времени выполнения утверждает.:(

Кроме того, не лучшие сообщения об ошибках.

7
ответ дан 8 December 2019 в 18:42
поделиться

Если по некоторым причинам Вы не можете использовать Повышение, этот пример тривиально записан как это:

template <int number1>
void reportErrorIfLessThan10()
{
    typedef char number1_gt_10[number1 > 10 ? 1 : -1];
}


int maint(int argc, char**argv)
{
   reportErrorIfLessThan10<5>();//report an error!
   reportErrorIfLessThan10<12>();//ok
   return 0;
}

Или более универсальный

#define static_assert(test, message) typedef char static_assert_at_ ## __LINE__[(test) ? 1 : -1];

Я не связываю само сообщение об ошибке, потому что я чувствую это static_assert(true, "some message"); более читаемо, чем говорят static_assert(true, some_message);. Однако это действительно ограничивает вариант использования только одним, утверждают на строку.

3
ответ дан 8 December 2019 в 18:42
поделиться
template <int number1>
typename boost::enable_if_c< (number1 >= 10) >::type 
reportErrorIfLessThan10() {
    // ...
}

Вышеупомянутое enable_if, без _c, потому что у нас есть плоскость bool, похож на это:

template<bool C, typename T = void>
struct enable_if {
  typedef T type;
};

template<typename T>
struct enable_if<false, T> { };

Повышение enable_if берет не плоскость bool, таким образом, у них есть другая версия, которой добавили _c, который берет плоскость bools. Вы не сможете назвать его для number1 <10. SFINAE исключит тот шаблон как возможных кандидатов, потому что enable_if не выставит тип ::type если условие оценивает к false. Если Вы хотите, по некоторым причинам, протестируйте его в функции, то, если у Вас есть C++ 1x доступная функция, можно использовать static_assert:

template <int number1>
void reportErrorIfLessThan10() {
    static_assert(number >= 10, "number must be >= 10");
}

В противном случае можно использовать BOOST_STATIC_ASSERT:

template <int number1>
void reportErrorIfLessThan10() {
    BOOST_STATIC_ASSERT(number >= 10);
}

Единственный способ отобразить описательное сообщение использует static_assert, все же. Можно более или менее моделировать это, с помощью типов, имеющих имена, которые описывают состояние ошибки:

namespace detail {
    /* chooses type A if cond == true, chooses type B if cond == false */
    template <bool cond, typename A, typename B>
    struct Condition {
      typedef A type;
    };

    template <typename A, typename B>
    struct Condition<false, A, B> {
      typedef B type;
    };

    struct number1_greater_than_10;
}

template <int number1>
void reportErrorIfLessThan10() {
    // number1 must be greater than 10
    sizeof( typename detail::Condition< (number1 >= 10), 
             char, 
             detail::number1_greater_than_10 
            >::type ); 
}

Это печатает это здесь:

ошибка: недопустимое приложение 'sizeof' к неполному типу 'деталь:: number1_greater_than_10'

Но я думаю самый первый подход, с помощью enable_if сделает это. Вы получите сообщение об ошибке о необъявленном reportErrorIfLessThan10.

3
ответ дан 8 December 2019 в 18:42
поделиться

litb и Joe уже дали ответы, используемые на практике. Только, чтобы проиллюстрировать, как это может быть сделано вручную путем специализации для рассматриваемого числа (а не общее булево условие):

template <int N>
struct helper : helper<N - 1> { };

template <>
struct helper<10> { typedef void type; };

template <>
struct helper<0> { }; // Notice: missing typedef.

template <int N>
typename helper<N>::type error_if_less_than_10() {
}

int main() {
    error_if_less_than_10<10>();
    error_if_less_than_10<9>();
}

Функции не могут быть наследованы, но классы (и структуры) могут. Поэтому этот код также использует структуру, которая автоматически и динамично генерирует случаи для всего N кроме 10 и 0, которые являются трудно кодированной рекурсией, начинается.

Между прочим, вышеупомянутый код на самом деле дает довольно хорошие сообщения об ошибках:

x.cpp:16: error: no matching function for call to 'error_if_less_than_10()'
0
ответ дан 8 December 2019 в 18:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: