Существует ли программа\инструмент, который по коду, в котором написан шаблон, определяет, как должен выглядеть класс T
, который используется как параметр шаблона:
Либо же говорит, что если подставить вместо T
какие-то классы, которые определены в коде, то он скомпилируется.
Пример:
Имеется такой шаблон функции:
template<class T>
void foo(T a)
{
T b = a;
boo(a, 1);
b = a - b;
a.foo2(b);
b.param = a.param;
T::foo1(b);
}
Анализируя этот код, программа говорит, что класс T
должен выглядеть примерно так:
class T
{
public:
T();
~T();
T(T&);
T operator-(T& b);
static void foo1(T);
void foo2(T);
UNKNOWN_TYPE param;
}
И для него должны быть перегружены такие функции:
void boo(T, INT_TYPE);
С какими параметрами он скомпилируется:
Функция foo скомпилируется, если в качестве параметра T использовать классы:
Class1, Class2, Class3<double>, Class3<float>.
Нет, это невозможно. Для решения этой проблемы вы (кроме полного парсера C++) должны решить алгоритмическую проблему останова, так как шаблоны в C++ полны по Тьюрингу. А значит, определить, скомпилируется данная подстановка или нет, равносильно тому, чтобы определить, завершится произвольный алгоритм или нет.
Вот вам небольшой [де]мотивирующий пример. Определим вспомогательный шаблон, который умеет вычислять степень числа во время компиляции:
template <unsigned int x, unsigned int n>
struct static_power
{
enum { value = static_power<x, n - 1>::value * x };
};
template <unsigned int x>
struct static_power<x, 0>
{
enum { value = 1 };
};
Рассмотрим теперь вот такой шаблон:
template<unsigned int x, unsigned int y, unsigned int z, unsigned int n>
struct Fermat
{
static_assert(n > 2, "Wrong power");
static_assert(static_power<x, n>::value + static_power<y, n>::value ==
static_power<z, n>::value, "Fermat proof");
};
Этот шаблон можно инстанциировать только с теми числами x
, y
, z
, n
, которые являются решением Великой теоремы Ферма.
Как вы думаете, легко ли написать программу, которая сможет автоматически доказать теорему Ферма?
Примечание. Проблема здесь не только в числовых параметрах. Шаблон можно переписать и так:
template<typename X, typename Y, typename Z, typename N>
struct Fermat
{
static_assert(N::value > 2, "Wrong power");
static_assert(
static_power<X::value, N::value>::value +
static_power<Y::value, N::value>::value ==
static_power<Z::value, N::value>::value,
"Fermat proof");
};
P. S.: Решить задачу простым перебором классов не получится, т. к. шаблоны приносят в программу по существу бесконечное множество классов.
Например, имея
template<typename T> struct X { /**/ };
мы определяем сразу X<void>
, X<X<void>>
, X<X<X<void>>>
и т. д.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Работаю с чужим окном из своей программыКак сделать так, чтобы все окна, которые открывает чужое (главное) окно сразу были скрытыми ? Сейчас...
Есть несколько элементов с классом testДля них я использую $('
Здравствуйте почему у меня не работает вот этот mixin в(scss) вот это mixin что я делаю не так