Можно ли выполнять ввод / вывод в функциях constexpr - PullRequest
0 голосов
/ 20 октября 2018
#include <iostream>

class test
{
public:
    constexpr void setX(int val);
private:
    int x;
};

constexpr void test::setX(int val)
{
    x = val;
    std::cout << "x : " << x << '\n';
}

int main()
{
    test obj;
    obj.setX(5);
    return 0;
}

Здесь возникает вопрос, я не могу выполнить операции ввода-вывода для отладки в этой функции constexpr.Так есть ли способ выполнять операции ввода-вывода внутри функции constexpr или это ограничение / поведение в C ++?

1 Ответ

0 голосов
/ 20 октября 2018

В настоящее время то, что у вас плохо сформировано, не требует диагностики согласно C ++ 11 [dcl.constexpr] p5 :

Для функции constexpr, если нет функцииЗначения аргумента существуют так, что подстановка вызова функции выдает константное выражение ([expr.const]), программа плохо сформирована;Диагностика не требуется.Для конструктора constexpr, если не существует значений аргумента, таких, что после подстановки вызова функции каждый вызов конструктора и полное выражение в mem-инициализаторах будет постоянным выражением (включая преобразования), программа будет плохо сформирована;Диагностика не требуется.[Пример:

constexpr int f(bool b)
  { return b ? throw 0 : 0; }               // OK
constexpr int f() { throw 0; }              // ill-formed, no diagnostic required

struct B {
  constexpr B(int x) : i(0) { }             // x is unused
  int i;
};

int global;

struct D : B {
  constexpr D() : B(global) { }             // ill-formed, no diagnostic required
                                            // lvalue-to-rvalue conversion on non-constant global
};

- конец примера]

, и если вы попытаетесь использовать его в контексте, требующем постоянного выражения, это станет серьезной ошибкой, например:

constexpr test obj;

см. Пример Godbolt в реальном времени .

Мы можем видеть из [expr.const] p2 , что мы ограничены в вызове constexpr функций:

вызов функции, отличной от конструктора constexpr, для литерального класса или функции constexpr [Примечание. Разрешение перегрузки ([over.match]) применяется как обычно - конец примечания];

и cout и другие функции ввода / вывода не помечены constexpr.

Кавычки для C ++ 14 аналогичны [dcl.constexpr] p5 и [expr.const] p2 .

...