2015-03-25 2 views
8

У меня есть эта очень простая функция, которая не будет компилироваться.constexpr void function reject

constexpr void func() 
{ 
} 

Ошибка я получаю:

error: invalid return type 'void' of constexpr function 'constexpr void func()' 

    constexpr void func()

В C++ 14, void является буквальным типа [§3.9/10]:

тип является литеральный тип если:

  • void; или
  • скалярный тип; или
  • ссылочный тип; или
  • массив литерального типа; или
  • типа класса (пункт 9), который имеет все из следующих свойств:
    • имеет тривиальный деструктор,
    • это совокупность типа (8.5.1) или имеет, по меньшей мере, один constexpr конструктор или конструктор, который не является конструктором копирования или перемещения, и
    • все его нестатические элементы данных и базовые классы являются нелетучими литералами.

Может кто-нибудь объяснить, почему это является недействительным?

+0

возможно дубликат (HTTP [Пустота как буквальный типа?]: // StackOverflow .com/questions/27486581/void-as-a-literal-type) –

+0

Ссылаясь на рабочий проект post-C++ 14, не очень полезно для доказательства фактов о C++ 14. –

ответ

5

Предложение, сделанное void, было n3652 Relaxing constraints on constexpr functions. G ++ решил толкнуть эту функцию до версии 5 (я использую 4.9.2):

G ++ теперь поддерживает C++ 14 расширенного constexpr.

constexpr int f (int i) 
{ 
    int j = 0; 
    for (; i > 0; --i) 
    ++j; 
    return j; 
} 

constexpr int i = f(42); // i is 42 

Clang была эта реализована начиная с версии 3.4.

5

Это действительно действительно, но еще не поддерживается в GCC. Пример в стандарте на самом деле включает в себя constexpr функции, возвращающей void - см [dcl.constexpr]/1:

constexpr void square(int &x); // OK: declaration 
// [..] 
constexpr void square(int &x) { // OK: definition 
    x *= x; 
} 

Example on Coliru с использованием Clang, который здесь соответствующий.

2

Взятые из C++ Programmig Язык (4-е издание):

Функция constexpr не может иметь побочные эффекты.

Итак, какова была бы функция constexpr void?

Если вы стремитесь сделать что-то вроде этого:

constexpr void Twice(int &a) 
{ 
    a *= 2; 
} 

Вы должны рассмотреть вопрос об изменении в:

constexpr int Twice(int a) 
{ 
    return 2 * a; 
} 
+4

Цель? Легко, например: template constexpr void requireIntegral() {static_assert (std :: is_integral :: значение, тип должен быть неотъемлемым); }; –

+0

Вы правы, хороший момент. Никогда не думал об использовании функций constexpr. –

Смежные вопросы