Статическое утверждение, если возможно, динамическое утверждение в противном случае?

Допустим, у меня есть шаблонная функция, которая принимает целое число и константную ссылку на экземпляр типа T. Теперь, в зависимости от целого числа, допустимы только некоторые T, в противном случае во время выполнения генерируется исключение.

Если бы во всех случаях использования этой функции использовались постоянные целые числа, можно было бы сделать int параметром шаблона и использовать статическое утверждение для проверки его приемлемости. Таким образом, вместо func(1,c)можно было бы использовать func<1>(c)и получить проверку типов во время компиляции -. Есть ли способ написать func(1,c)и по-прежнему сохранять проверку времени компиляции -, а также иметь возможность написать func(i,c)и использовать динамическое утверждение? Цель состоит в том, чтобы сделать его прозрачным для разработчика. Было бы просто здорово добавить эту безопасность, не беспокоя разработчиков такими вещами, как константы времени компиляции -. Они, вероятно, только помнят, что func(1,c)всегда работает, и используют это, избегая проверки.

Как я могу определить функцию со статическим утверждением, когда это возможно, и динамическим утверждением в противном случае?


Следующий код показывает решение для GCC Ивана Щербакова:

#include <iostream>
#include <cassert>

template<typename T>
void __attribute__((always_inline)) func(const int& i, const T& t);

void compile_time_error_() __attribute__((__error__ ("assertion failed")));

template<>
  void __attribute__((always_inline))
  func(const int& i, const float& t)
{
    do {
        if (i != 0) {
            if (__builtin_constant_p(i)) compile_time_error_();
            std::cerr << "assertion xzy failed" << std::endl;
            exit(1);
        }
    } while (0);
    func_impl<float>(i,t);
}

Это позволит только комбинацию i=0 и T=float. Для других комбинаций хорошим способом было бы создание макроса, который создает код template<> func(const int& i, const T& t)с заменой T и i != 0.

11
задан Tar 14 July 2012 в 07:23
поделиться