所以,玩弄constexpr,MSVC(Visual Studio 2012)给了我一个错误,而试图使用这个简单的程序(包括省略)与constexpr关键字限定我的function: constexpr int factorial(int n) { return n <= 1 ? 1 : (n * factorial(n-1)); } int main(void) { const int fact_three = factorial(3); std::cout << fact_three << std::endl; return 0; } constexpr被强调为红色并带有以下信息: 错误:此声明没有存储类或types说明符 并试图编译该程序给出了以下输出: 1> main.cpp(5):错误C2144:语法错误:'int'应该以';'开头 1> main.cpp(5):错误C4430:缺lesstypes说明符 – int假定。 注意:C ++不支持default-int 它真的令我困惑,因为它是Cppreference 用来说明constexpr的使用的一个例子。 起初,我用一个简单的函数返回一个文字,即constexpr int func(){return 5;} ,但是产生了相同的错误。 我将第一条消息解释为“它应该是一个结构或类的成员函数”,但Cppreference的例子显示它不是必要的。 那么,我显然在这里错过了什么?
相关: 函数返回constexpr不编译 我觉得constexpr在C ++ 11中的用处是有限的,因为它不能定义两个函数,否则它们会有相同的签名,但是一个是constexpr,另一个是不是constexpr。 换句话说,如果我可以有一个constexst std :: string构造函数,它只需要constexpr参数,而一个非constexpr std :: string构造函数用于非constexpr参数将是非常有帮助的。 另一个例子是理论上复杂的函数,可以通过使用状态来提高效率。 你不能用constexpr函数轻松做到这一点,所以你只剩下两个select:如果你传递了非constexpr参数,或者完全放弃了constexpr(或者写了两个单独的函数,但你可能不知道要调用哪个版本)。 因此,我的问题是: 标准兼容的C ++ 11实现是否可以允许基于constexpr参数的函数重载,还是需要更新标准呢? 如果不允许,是否故意不允许? @NicolBolas:说我有一个函数,将一个enum映射到一个std::string 。 假设我的enum从0到n – 1 ,最直接的方法是创build一个大小为n的数组,填充结果。 我可以创build一个static constexpr char const * []并在返回时构造一个std::string (每次调用该函数时支付创build一个std::string对象的代价),或者我可以创build一个static std::string const []并返回我查找的值,在第一次调用函数时支付所有std::string构造函数的代价。 看起来更好的解决scheme是在编译时在内存中创buildstd::string (类似于char const *所做的),但唯一的方法是提醒构造函数它有constexpr参数。 除了std::string构造函数以外,我认为find一个例子,如果你可以忽略constexpr的需求(从而创build一个非constexpr函数),那么你可以创build一个更多的例子高效的function。 考虑这个线程: constexpr问题,为什么这两个不同的程序在g ++中运行的时间不同? 如果我用一个constexpr参数来调用fib ,那么我完全可以比编译器优化掉函数调用来做得更好。 但是如果我用一个非constexpr参数来调用fib ,我可能希望让它调用我自己的版本来实现像memoization(这将需要状态),所以我得到的运行时间类似于我通过编译的时间一个constexpr论据。
假设我有一些constexpr函数f: constexpr int f(int x) { … } 我在编译时有一些const int N: 或 #define N …; 要么 const int N = …; 根据您的答案需要。 我想要一个int数组X: int X[N] = { f(0), f(1), f(2), …, f(N-1) } 这样在编译时计算函数,X中的条目由编译器计算,结果放在我的应用程序映像的静态区域,就好像我在我的X初始化列表中使用了整数文字一样。 有什么方法可以写这个吗? (例如使用模板或macros等) 我有最好的(谢谢柔印) #include <iostream> #include <array> using namespace std; constexpr int N = 10; constexpr int f(int x) { return […]
所以从这个页面上注意到,在c ++ 11中没有一个math函数似乎使用了constexpr,而我相信它们都可以。 所以这给我留下了两个问题,一个是他们为什么不selectfunction。 一个像sqrt这样的函数我可以写自己的constexpr,但是像sin或者cos这样的东西会更棘手,所以围绕它就会出现。
C ++ 11允许使用constexpr说明符声明的函数在常量expression式(如模板参数)中使用。 有关什么是可以被constexpr有严格的要求; 本质上这样一个函数只封装一个子expression式,没有别的。 (编辑:这是放松的C + + 14中,但问题的立场。) 为什么要求关键字呢? 获得了什么? 它确实有助于揭示接口的意图,但是它并没有validation意图,通过保证函数在常量expression式中是可用的。 在编写constexpr函数之后,程序员仍然必须: 编写一个testing用例或以其他方式确保它在一个常量expression式中被使用。 在常量expression式上下文中logging哪些参数值是有效的。 与揭示意图相反,装饰函数与constexpr可能会增加一个错误的安全感,因为切向语法约束被检查而忽略了中心语义约束。 简而言之 ,如果函数声明中的constexpr只是可选的,会不会对语言产生不良影响? 或者是否对任何有效的程序都有影响?
此Constexpr代码不在Visual Studio 2013版本12.0.21005.1 REL中编译 是否有一个新的Visual Studio编译器与constexpr一起工作? #include <iostream> constexpr int factorial(int n) { return n <= 1 ? 1 : (n * factorial(n – 1)); } int main(void) { const int fact_three = factorial(3); std::cout << fact_three << std::endl; return 0; } 编译输出: 1> ——开始生成:Project:Project1,configuration:Debug Win32 —— 1> Source.cpp 1> …. \ source.cpp(3):错误C2144:语法错误:'int'应该以';'开始 1> …. […]
我们知道C ++模板元编程是图灵完备的 ,但是预处理元编程不是 。 C ++ 11为我们提供了一种新的元编程forms:计算constexpr函数。 这种计算forms是否是图灵完成的? 我在想,因为recursion和条件运算符(?:)在constexpr函数中是允许的,但是我希望有更多专业知识的人来确认。
比方说,我有一个像这样定义的整数数组: static constexpr int IntArray[] = {1, 5, 10, 12, 17}; 有没有办法在编译时获得最小值或最大值?
下面的代码通过指数式慢algorithm计算斐波纳契数: #include <cstdlib> #include <iostream> #define DEBUG(var) { std::cout << #var << ": " << (var) << std::endl; } constexpr auto fib(const size_t n) -> long long { return n < 2 ? 1: fib(n – 1) + fib(n – 2); } int main(int argc, char *argv[]) { const long long fib91 = fib(91); DEBUG( […]
任何由return语句组成的函数都可以声明为constexpr ,因此,如果所有参数都是constexpr并且只有constexpr函数在其主体中被调用,则可以在编译时进行评估。 是否有任何理由不宣布这样的函数constexpr ? 例: constexpr int sum(int x, int y) { return x + y; } constexpr i = 10; static_assert(sum(i, 13) == 23, "sum correct"); 任何人都可以提供一个例子,声明一个函数constexpr会有什么危害吗? 一些最初的想法: 即使不应该声明一个函数不是constexpr充分理由,我可以想象constexpr关键字具有过渡性作用:在代码中不需要编译时评估的编译器不允许编译器评估仍然要编译该代码(但是需要使用constexpr显示需要的代码时可靠地失败)。 但是我不明白:如果没有充分的理由宣布一个function不够完善的话,为什么标准库中的每一个function都没有被宣告为constexpr ? (你不能争辩说还没有完成,因为还没有足够的时间去做,因为这样做是毫不费力的 – 与决定每一个单一function是否相反)。 – – 我知道, N2976故意不要求许多标准库types(如容器)的cstrs,因为这对于可能的实现来说太过于限制。 让我们把它们排除在参数之外,只是想知道:一旦标准库中的types实际上有一个constexpr cstr,为什么不是每个函数都声明为constexpr呢? 在大多数情况下,你也不能争辩说,你可能宁愿不去声明一个函数constexpr只是因为你没有设想任何编译时间的用法:因为如果其他人evtl. 将使用你的代码,他们可能会看到你不这样使用。 (但是,当然,types特征types和东西都是可以的。) 所以我想有一个很好的理由和一个很好的例子,故意不宣布函数constexpr ? (“每一个function”,我的意思是:每一个符合被constexpr要求的函数,也就是被定义为一个单一的return语句,只带有constexprcrstypes的参数,只调用constexpr函数。 问题为什么std::forward放弃了constexpr -ness? 这是一个特例。