Здравствуйте, _NN_, Вы писали:
_NN>Возможно ли делать разные действия в зависимости от возможности получения значения во времени компиляции ? _NN>Например:
_NN>
_NN>template<typenmae T>
_NN>auto f(T const& t)
_NN>{
_NN> return 1;
_NN>}
_NN>constexpr auto f(int t) // для int constexpr, для остальных нет
_NN>{
_NN> return 2;
_NN>}
_NN>
_NN>Я хочу написать функцию g с различным поведением, псевдокод _NN>
Здравствуйте, _NN_, Вы писали:
_NN>Возможно ли делать разные действия в зависимости от возможности получения значения во времени компиляции ?
Можно сделать макрос, который будет вызывать различные реализации функции в зависимости от того, являются ли аргументы константами времени компиляции, примерно так: https://stackoverflow.com/a/40413051/305118
Здравствуйте, nikov, Вы писали:
_NN>>Возможно ли делать разные действия в зависимости от возможности получения значения во времени компиляции ?
N>Можно сделать макрос, который будет вызывать различные реализации функции в зависимости от того, являются ли аргументы константами времени компиляции, примерно так: https://stackoverflow.com/a/40413051/305118
Expands to the strongest form of assertion possible for the given condition. Given a condition, BOOST_HANA_ASSERT expands either to a compile-time or to a runtime assertion, depending on whether the value of the condition is known at compile-time or at runtime.
Здравствуйте, vopl, Вы писали:
_NN>>А как воспользоваться результатом f(t), чтобы было во времени компиляции ?
V>Для этого надо чтобы значение t было компайл-тайм константой, например так
[добавка]
либо, если домен значений t не велик — можно построить транслятор из рантайма в компайл-тайм, примерно так
template<typenmae T>
auto g(T const& t)
{
if(is_f_constexpr_for<T>())
{
switch(t)
{
case 0: return Integer<f(0)>::value;
case 1: return Integer<f(1)>::value;
case 2: return Integer<f(2)>::value;
case 3: return Integer<f(3)>::value;
default:
//throw "случилось плохое значение t, для него нет компайл-тайм реализации";return f(t) + 20;
}
}
else
{
return f(t) + 20;
}
}
Здравствуйте, vopl, Вы писали:
V>Можно на основе SFINAE определить, является ли f constexpr для заданного T, примерно так
Что-то я не очень понимаю, какую задачу ты решал. Любое выражение типа int у тебя обрабатывается как constexpr, даже если оно таковым не является: здесь. Такого же поведения можно было добиться обычной перегрузкой для типа int без всякого SFINAE. Но, как я понимаю, это не то, чего ждал ТС.
--
Не можешь достичь желаемого — пожелай достигнутого.
Насколько я знаю, невозможно внутри функции определить каким выражением был сформирован фактический параметр (constexpr/non-constexpr), это можно сделать только "снаружи", в точке вызова. Поэтому здесь лучше сразу смотреть в сторону подхода, предложенного Nikov.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, _NN_, Вы писали:
_NN>>Возможно ли делать разные действия в зависимости от возможности получения значения во времени компиляции ?
N>Можно сделать макрос, который будет вызывать различные реализации функции в зависимости от того, являются ли аргументы константами времени компиляции, примерно так: https://stackoverflow.com/a/40413051/305118
Спасибо.
Мне по сути нужно только поменять возвращаемый тип (продолжение топика с std::array::size
Возможно тут будет вариант попроще?
Или хотя бы макрос не выставлять наружу, а только внутри size_smallest.
template<unsigned long long Value>
constexpr auto size_smallest_type()
{
// возвращаем наименьший тип в который влезает Value.
}
template<typename Container>
auto size_smallest(Container const& container)
{
if constexpr-expression std::size(container)
{
return size_smallest_type<std::size(container)>(); // Возвращаемый тип будет наименьшим необходимым
}
else
{
return std::size(container); // Возвращаемый тип будет size_t
}
}
// Используем
DWORD WINAPI GetModuleFileName(
_In_opt_ HMODULE hModule,
_Out_ LPTSTR lpFilename,
_In_ DWORD nSize
);
std::array<char, 100> buf;
GetModuleFileName(nullptr, std::data(buf), size_smallest(buf)); // нет проблем с компиляцией, т.к. size_smallest(buf) имеет тип unsigned char
P.S.
Самый трепещущий всех вопрос, почему господин nikov занимается плюсами ?
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, vopl, Вы писали:
V>>Можно на основе SFINAE определить, является ли f constexpr для заданного T, примерно так
R>Что-то я не очень понимаю, какую задачу ты решал.
определить, является ли "f(чето)" — constexpr выражением
R>Любое выражение типа int у тебя обрабатывается как constexpr, даже если оно таковым не является: здесь.
хм.. Плохой пример? В нем вижу буквально следующее
constexpr auto f(int) // для int constexpr, для остальных нет
То есть, не показана ситуация "даже если оно таковым не является"
>>Такого же поведения можно было добиться обычной перегрузкой для типа int без всякого SFINAE. Но, как я понимаю, это не то, чего ждал ТС.
давай я уберу constexpr для int и повставляю его для тругих типов здесь
Здравствуйте, _NN_, Вы писали:
_NN>Самый трепещущий всех вопрос, почему господин nikov занимается плюсами ?
Потому что с марта 2017 я работаю в Synopsys, Coverity Analysis, пишу статический анализ для плюсов (и для других языков), на плюсах. Потихоньку зубрю Стандарт C++
Здравствуйте, rg45, Вы писали: R>Здравствуйте, vopl, Вы писали: V>>хм.. Плохой пример? В нем вижу буквально следующее V>>
constexpr auto f(int) // для int constexpr, для остальных нет
V>>То есть, не показана ситуация "даже если оно таковым не является" R>Как это не показана? Фактический параметр (i) функции g здесь не является constexpr выражением: R>
А.. понял о чем ты. Задача, которую я решал звучит так: "определить, является ли конкретная перегрузка "R f(T)" — constexpr функцией". Ты же приводишь немного другой кейс, "определить, является ли поданное (извне) значение/выражение — компайл-тайм константой". Согласен, что твой аспект так же является актуальным в оригинальном вопросе ТС.
По твоему кейсу — согласен с твоим же высказыванием отсюда
Здравствуйте, _NN_, Вы писали:
_NN>Возможно ли делать разные действия в зависимости от возможности получения значения во времени компиляции ?
Кстати, я нашел два документа, касающихся этого вопроса. Там предлагаются изменения в c++, которые позволили бы делать это более естественным и удобным образом: