constexpr
functions不应包含:
A definition of a variable of non-literal type
但是在这个答案中,一个 lambda 被定义在一个:https://stackoverflow.com/a/41616651/2642059
template <typename T>
constexpr auto make_div(const T quot, const T rem)
{
return [&]() {
decltype(std::div(quot, rem)) result;
result.quot = quot;
result.rem = rem;
return result;
}();
}
在我的评论中,我在其中定义了一个 div_t
:How can I Initialize a div_t Object?
template <typename T>
constexpr decltype(div(T{}, T{})) make_div(const T quot, const T rem)
{
decltype(div(T{}, T{})) x{};
x.quot = quot;
x.rem = rem;
return x;
}
禁止“定义非字面量类型的变量”到底是什么意思?
Visual Studio 2015 不允许我定义 div_t
,但我发现允许将此类非法行为包装在 lambda 中并执行它是荒谬的。我想知道哪个编译器在 div_t
定义方面的行为是否正确。
最佳答案
几乎可以保证,如果存在差异,gcc 的行为是正确的,因为 Visual Studio 2015 不支持 c++14 constexpr
的扩展:https://msdn.microsoft.com/en-us/library/hh567368.aspx#C-14-Core-Language-Features
C++11 constexpr
函数
函数体只能包含:
- null statements (plain semicolons)
static_assert
declarationstypedef
declarations and alias declarations that do not define classes or enumerationsusing
declarationsusing
directives- exactly one
return
statement
所以 c++11不能容忍 decltype(div(T{}, T{})) x{}
的定义。然而,滚动建议的三元组是可以接受的 here在 constexpr
函数中实现相同的结果:
template <typename T>
constexpr auto make_div(const T quot, const T rem)
{
using foo = decltype(div(T{}, T{}));
return foo{1, 0}.quot != 0 ? foo{quot, rem} : foo{rem, quot};
}
C++14 constexpr
函数
函数体可以包含除之外的任何内容:
- an asm declaration
- a goto statement
- a statement with a label other than case and default
- a try-block
- a definition of a variable of non-literal type
- a definition of a variable of static or thread storage duration
- a definition of a variable for which no initialization is performed
定义“文字类型”的位置 here ,虽然特别针对对象,但它们可能是具有普通析构函数的聚合类型。所以 div_t
绝对符合条件。因此c++14 ,并且通过扩展 gcc,可以容忍 decltype(div(T{}, T{})) x{}
的定义。
C++17 constexpr
函数
C++17 在“文字类型”的定义中增加了对闭包类型的支持,所以我觉得奇怪的是 gcc 和 Visual Studio 都支持在 return
语句中使用 lambda。我想这要么是前瞻性支持,要么是编译器选择内联 lambda。无论哪种情况,我都不认为它符合 c++14 的条件。 constexpr
函数。
[ Source ]
关于c++ - constexpr 函数允许什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41618576/