Я пишу библиотеку, в которой параметры объекта, которые по своей природе являются статическими, встроены в тип с использованием нетиповых параметров шаблона. Это обеспечивает массовую оптимизацию производительности по сравнению с реализацией, где эти значения являются значениями времени выполнения (небольшие тесты, измеренные в 10 раз, ожидаемые в 5-7 раз). Однако я считаю, что C ++ не очень хорошо поддерживает эту идиому. Я пытаюсь реорганизовать библиотеку, чтобы упростить ее использование разработчиками, которые не очень знакомы с шаблонами или метапрограммированием.
Я хотел бы предложить constexpr
функции, которые упрощают извлечение элемента static constexpr
переменные (которые используются для распространения статических значений через типы), так что пользователи могут выполнять некоторые базовые метапрограммирования, не понимая тяжелой техники за кулисами. Например,
#include <type_traits>
template <int A, int B>
class Example {
public:
static constexpr auto C = A + B;
private:
int b {0};
};
template <int A, int B>
constexpr auto getC(Example<A, B> e) { return decltype(e)::C; }
/**** USER CODE ****/
int main()
{
Example<1, 2> e;
Example<2, getC(e)> f;
}
Это не работает, e
, не являющийся constexpr, может использоваться в контексте constexpr, даже если вы не используете значение (странно, если Example
не имел времени выполненияЧлены, это будет работать). Вместо этого можно было бы написать decltype(e)::C
, но если это ссылка, они должны были бы std::remove_reference<decltype(C)>::type::C
, и, конечно, они должны были бы знать, чтобы сделать это, и знать достаточно, чтобы обойти общие проблемы, такие как вызов remove_reference
. И в этот момент мы отключены для типичного программиста, для которого предназначена эта библиотека.
constexpr
функции не работают, макросы не работают с системой типов, поэтому их также недостаточно,как еще я мог это сделать?