C ++ Создать переменную, только если аргумент шаблона равен true - PullRequest
0 голосов
/ 08 июня 2019

Есть ли способ создать переменную в функции, только если аргумент шаблона имеет значение true?

template<bool _CalcExtra>
int foo()
{
    int local;
    int local2;

    for(work)
    {
        ... work using local
        if(_CalcExtra)
            ... additional work using local and local2
    }

    if(_CalcExtra)   
        return local2;
    return local;
}

Я предполагаю, что большинство компиляторов просто удаляют local2, когда функция вызывается следующим образом

foo<false>();

но есть ли программный способ убедиться, что local2 никогда не выделяется?

Ответы [ 2 ]

4 голосов
/ 08 июня 2019

Не существует (стандартного) способа узнать, какие переменные будут размещены в стеке, что будет помещено только в регистры, а что просто отброшено.Временные потоки также могут быть разбросаны по стеку.

Здесь тривиальная оптимизация - удаление этих ветвей.Вы можете использовать if constexpr, чтобы убедиться, что это так.

Вы также можете посмотреть на сгенерированный код сборки, чтобы посмотреть, что выделено или нет.

В крайнем случае, вы можете захотетьспециализируете, чтобы вы работали вручную со значением параметра, и только с использованием local2 в специализации false.

Обратите внимание, что выделения в стеке свободны вне использования пространства стека ... Это просто перемещаетуказатель стека при входе в функцию на 4 байта больше.

1 голос
/ 08 июня 2019

В общем случае не гарантируется, что или local или local2 выделены, по крайней мере, в том смысле, что им дано место в памяти. Компиляторы часто используют регистры ЦП для хранения локальных переменных, а компиляторы присваивают регистру переменные только тогда, когда

  • им присвоено значение
  • код использует их каким-то образом

Неиспользуемые переменные часто полностью исключаются, и компилятор не создает никакой соответствующей им сборки.

Единственное исключение из этого, если у конструктора переменной есть какой-то побочный эффект, который может быть видимым (например, если он открывает файл или печатает что-то при его создании).

При этом вы можете условно убедиться, что компилятор не создаст никакой сборки, соответствующей local2, даже в режиме отладки , с помощью оператора if constexpr (introducd в C ++ 17): * 1 021 *

template<bool _CalcExtra>
int foo()
{
    int local;

    if constexpr(_CalcExtra) {
        int local2;

        for(...)
        {
            ... work using local
            ... additional work using local and local2
        }

        return local2; 
    } else {
        for(...)
        {
            ... work using local
        }

        return local; 
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...