我认为在C++ 14中,从constexpr中删除了更多限制.但根据N3797 7.1.5 3-punct:
contexpr函数shal的定义满足以下约束:
我知道为什么静态,线程存储持续时间变量是不允许的,但我没有看到任何理由,为什么只允许定义一个文字类型的变量?
或者我不明白标准.
我不确定,但是根据标准的跟随错误应该创建,即使是C++ 14:
struct point{
constexpr point(): x(0), y(0){}
constexpr point(int x_, int y_): x(x_),y(y_){}
constexpr int hypot()const { return x*x + y*y; }
int x,y;
};
constexpr int hypot(int x, int y) {
point p{x,y}; //error, because p - is not literal type.
return p.hypot();
}
// error, because return type …Run Code Online (Sandbox Code Playgroud) 我有如下功能:
const char* get_message() {
return "This is a constant message, will NOT change forever!";
};
const char* get_message2() {
return "message2";
};
Run Code Online (Sandbox Code Playgroud)
我计划在我的应用程序的任何地方使用它们,即使在不同的线程中。
const char*我想知道这些字符串的生命周期,即在函数之外使用这些字符串是否安全get_message。
我猜想硬编码const char*字符串将被编译到应用程序的代码段而不是数据段中,所以也许像上面那样使用它们是安全的?
为什么不编译:作为返回类型
会出现问题string吗?
constexpr std::string fnc()
{
return std::string("Yaba");
}
Run Code Online (Sandbox Code Playgroud) 你会替换吗?
const int one = 1;
const int two = 2;
Run Code Online (Sandbox Code Playgroud)
有了这个?
constexpr int one = 1;
constexpr int two = 2;
Run Code Online (Sandbox Code Playgroud)
我的理解是正确的,两个块在语义上是相同的,并且它目前只是一个品味的问题?
另一方面,正如constexpr所暗示的那样const,你可以争辩说,总是更喜欢更具限制性的形式更为一致,即使是在无关紧要的微不足道的情况下也是如此?
(我理解当右侧的表达式允许更复杂时,情况会完全改变.因此,为了澄清,问题只关注表达式是固定整数的最简单的情况.)
说我有
constexpr const std::uint8_t major = 1;
constexpr const std::uint8_t minor = 10;
constexpr const std::uint8_t bugfix = 0;
Run Code Online (Sandbox Code Playgroud)
而且我要
constexpr const char* version_string(){ ... }
Run Code Online (Sandbox Code Playgroud)
要返回"1.10.0"本例中的等价物,我该怎么做?
我假设我需要这两个,在constexpr:
这个问题纯粹是学术性的,constexpr除了"有可能"之外,我认为实际上没有任何用处.我只是看不出这会如何发展.我愿意接受适用于GCC 4.9和Clang 3.4/3.5的C++ 1y解决方案.
我相信我在日本的一些博客上发现了几乎所有的东西:
我会看到我能用这些做些什么,也许当我对结果感到满意时,我自己回答这个自称有趣的问题.
constexpr我的库中有几个简短的函数可以执行一些简单的计算.我在运行时和编译时上下文中都使用它们.
我想在这些函数的主体中执行一些断言,但是assert(...)在constexpr函数中无效并且static_assert(...)不能用于检查函数参数.
例:
constexpr int getClamped(int mValue, int mMin, int mMax) noexcept
{
assert(mMin <= mMax); // does not compile!
return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法检查函数是在运行时或编译时常量中执行还是assert只在运行时执行它才执行?
constexpr int getClamped(int mValue, int mMin, int mMax) noexcept
{
assert_if_runtime(mMin <= mMax);
return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
Run Code Online (Sandbox Code Playgroud) 这是我的工作代码示例:
#include <iostream>
template<typename B>
class b {
public:
int y;
constexpr b(int x) : y(x) {
}
constexpr void sayhi() {
std::cout << "hi" << std::endl;
}
};
template<int x>
struct A {
static constexpr b<int> bee = x;
static constexpr int y = x; // this one is fine and usable already, I don't have to do something like what I did on member bee
inline static void sayhi() {
std::cout << y << std::endl;
}
};
template<int …Run Code Online (Sandbox Code Playgroud) 我正在制定一个提出功能头功能的提议constexpr.(std::invoke,std::reference_wrapper,std::bind,std::mem_fn,std::not_fn)
我已经了解到添加constexpr可以破坏现有代码,因为constexpr函数是急切实例化的.
template<class T>
int f(T){
return T::not_existing_member;
}
template<class T>
constexpr int g(T){
return T::not_existing_member;
}
int main(){
decltype(f(0)) a; // Well-formed
decltype(g(0)) b; // Ill-formed if the function body is instantiated
}
Run Code Online (Sandbox Code Playgroud)
GCC编译这段代码,clang没有.我在我的提议中描述了如何使用示例来处理带有重载的急切实例化std::bind.
你能告诉我编译器必须在标准中描述的位置,以及何时允许实例化一个功能模板?
更确切地说,我想知道在以下示例中,GCC和clang的相同行为是由标准强制执行还是实现定义:
template<class T>
struct Foo{
constexpr int f(){
return 0;
}
constexpr int f()const{
return T::not_existing_member;
} …Run Code Online (Sandbox Code Playgroud) 我在以下位置定义了以下用户定义的文字MyLiteral.h:
namespace my_literals {
constexpr uint64_t operator"" _nanoseconds(unsigned long long int value) {
return value*1000;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我可以在另一个标题中使用运算符SomeComponent.h:
using namespace my_literals;
namespace foo {
constexpr uint64_t timeout = 10_nanoseconds;
}
Run Code Online (Sandbox Code Playgroud)
但是,我不想污染范围using namespace my_literals,因为这会为*.cpp包含的所有文件提供文字定义SomeComponent.h.
我怎么能避免这个?在g ++中constexpr uint64_t timeout = my_literals::10_nanoseconds;给出数字常量之前的预期unqualified-id.
根据某种条件在几个已知范围之一上进行迭代的最有效方法是什么?
二进制条件的伪代码:
for element in (condition ? range_a : range_b)
// do work
Run Code Online (Sandbox Code Playgroud)
这个“示例”显示了我使用基于范围的for循环的意图,但由于std::initializer_list具有参考语义,因此无法使用。
for element in (condition ? range_a : range_b)
// do work
Run Code Online (Sandbox Code Playgroud)
产量: warning: returning address of local temporary object [-Wreturn-stack-address]
在运行时,我可以返回a,std::vector但这将涉及在每次调用时构造一个新的向量:
constexpr auto some_range(bool c) -> std::initializer_list<int> {
if (c) {
return {1,2};
} else {
return {3, 4, 5};
}
}
bool cond = true; // false
for(auto x : some_range(cond)) {
// things
}
Run Code Online (Sandbox Code Playgroud)
我可以使用的固定大小std::array …