如果我使用specialized编写一个编译时阶乘函数,下面的代码就足够了,并且正确地提供120作为结果fact1<5>():
template <size_t N>
constexpr size_t fact1() { return N*fact1<N-1>(); }
template <>
constexpr size_t fact1<0>() { return 1; }
Run Code Online (Sandbox Code Playgroud)
但是,对于单个函数体和三元运算符,如下面的代码所示,G ++ 4.7和Clang ++ 3.2都超过了它们的最大模板实例化深度.它似乎1从未返回fact2.为什么这个定义fact2<5>()不会返回120?
template <size_t N>
constexpr size_t fact2() { return N==0 ? 1 : N*fact2<N-1>(); }
Run Code Online (Sandbox Code Playgroud) clang ++给出以下警告(见下面的代码):
'constexpr'非静态成员函数在C++ 1y中不会隐式'const'; 添加'const'以避免行为发生变化
应该在哪里const添加?const constexpr size_t getSize() {再发一次警告:
返回类型的'const'类型限定符无效
码:
constexpr size_t getSize()
{
return sizeof(header);
}
Run Code Online (Sandbox Code Playgroud) 从N4140§5.19/2.3(强调我的)
- 调用未定义的 constexpr函数或 未定义的 constexpr构造函数;
从§7.1.5/ 2开始,constexpr函数和构造函数是隐式内联的,也就是说,如果未在TU中定义constexpr函数,则代码将无法编译.
在C++ Primer,第五版,§6.5.2中:
甲
constexpr函数被定义像任何其他的功能,但必须满足某些限制:返回类型和每一个参数的类型必须是文字型,和函数体必须只包含一个返回语句(第2.4.4节,第66页.)
但本章的另一句话(第239页):
允许constexpr函数返回不是常量的值
Run Code Online (Sandbox Code Playgroud)// scale(arg) is a constant expression if arg is a constant expression constexpr size_t scale(size_t cnt) { return new_sz() * cnt; }
这是一个矛盾的总结吗?我很困惑.
返回类型scale是文字类型?
更新:文字类型和常量之间有什么区别?
clang拒绝了gcc允许的代码:
int main() {
static constexpr const void *vp = nullptr;
static constexpr const char *cp = static_cast<const char*>(vp);
}
Run Code Online (Sandbox Code Playgroud)
具有以下内容:
error: constexpr variable 'cp' must be initialized by a constant expression
static constexpr const char *cp = static_cast<const char*>(vp);
Run Code Online (Sandbox Code Playgroud)
在阅读N3797 5.9/2中的最终列表后,我没有看到任何禁止static_cast在常量表达中使用的内容.我是在寻找错误的地方还是误读了什么?或者我应该打开一个反对clang的bug?
编译时:
constexpr double x {123.0};
constexpr double y = x / 0.0;
std::cout << x << " / 0 = " << y << "\n";
Run Code Online (Sandbox Code Playgroud)
编译器(gcc 4.9.2,-std = c ++ 11或c ++ 14)失败,给出错误:
(1.23e+2 / 0.0)' is not a constant expression
constexpr double y = x / 0.0;
Run Code Online (Sandbox Code Playgroud)
在决定是否y可以成为constexpr时,结果(Inf)如何相关?
作为参考,这似乎是这样做的方式:
static constexpr double z = std::numeric_limits<double>::quiet_NaN();
static constexpr double w = std::numeric_limits<double>::infinity();
Run Code Online (Sandbox Code Playgroud) 使用gcc(HEAD 7.0.0 201612)我很惊讶地发现这有效:
constexpr long value(const char *definition)
{
if (definition && *definition)
{
return *definition + value(definition + 1);
}
return *definition;
}
int main()
{
long l{};
std::cin >> l;
switch (l)
{
case value("AAAA"): f1(); break;
case value("BBBB"): f2(); break;
default: error(); break;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
的文字串"AAAA"和"BBBB"被当作编译时值和调用value函数产生的值260和264直接在使用switch上下文; 我应该承认我期待编译器抱怨" 字符串不是常量表达式 ".所以我转到下一步并尝试添加一个if constexpr算法:
constexpr long value(const char *definition)
{
if constexpr (definition && *definition) …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用模板类(此处Foo),其基本类型如下:
hana::tuple<hana::pair<hana::type<int>, Runtime>>与Runtime一个不可思议的课程constepxr.但是类型可以用几种方式构造,这就是我使用的原因:
hana::tuple<hana::pair<hana::type<int>, hana::type<Runtime>>> 在编译时完成工作.所以问题基本上是如何从第一个元组转换为第二个类型.我想知道是否有什么hana可以帮助我.或者甚至更好,关于那种"转换"的一些提示.
namespace hana = boost::hana;
using namespace hana::literals;
struct Runtime { std::vector<int> data; };
template < typename T >
struct Foo {
T data;
};
constexpr decltype(auto) convertMap(auto storageMap) {
return hana::make_type(hana::transform(
storageMap,
[] (auto pair) {
return hana::make_pair(
hana::first(pair),
typename decltype(hana::typeid_(hana::second(pair)))::type {});
}));
}
int main() {
constexpr auto map = hana::make_tuple(
hana::make_pair(hana::type_c<int>, hana::type_c<Runtime>)
);
constexpr auto result = convertMap(map);
static_assert(result == …Run Code Online (Sandbox Code Playgroud) 所以说我想制作一些constexpr仿函数,虽然我可以使用它bind.有什么我想念的吗?为什么不能bind退货constexpr?
鉴于:
struct foo {
int b() const { return _b; }
int a() const { return _a; }
int r() const { return _r; }
const int _b;
const int _a;
const int _r;
};
Run Code Online (Sandbox Code Playgroud)
我想要:
constexpr auto sumB = bind(plus<int>(), placeholders::_1, bind(&foo::b, placeholders::_2));
constexpr auto sumA = bind(plus<int>(), placeholders::_1, bind(&foo::a, placeholders::_2));
constexpr auto sumR = bind(plus<int>(), placeholders::_1, bind(&foo::r, placeholders::_2));
Run Code Online (Sandbox Code Playgroud)
有什么我可以做的工作吗?
该代码在GCC 8中编译,但不在GCC 7和clang中编译。
constexpr int a = 1;
constexpr int b = --const_cast<int&>(a);
Run Code Online (Sandbox Code Playgroud)
这显然是UB。
我的问题:Standardese对评估包含UB的constexpr有什么看法-此代码应该完全编译吗?