我有一个名为access的constexpr函数,我想从数组中访问一个元素:
char const*const foo="foo";
char const*const bar[10]={"bar"};
constexpr int access(char const* c) { return (foo == c); } // this is working
constexpr int access(char const* c) { return (bar[0] == c); } // this isn't
int access(char const* c) { return (bar[0] == c); } // this is also working
Run Code Online (Sandbox Code Playgroud)
我收到错误:
error: the value of 'al' is not usable in a constant expression
Run Code Online (Sandbox Code Playgroud)
为什么我不能从访问中访问其中一个元素?或者更好我该怎么做,如果有可能的话?
我想做这样的事情:
template <typename T>
constexpr ::std::size_t type_name_hash()
{
return ::std::hash<::std::string>()(typeid(T).name());
}
Run Code Online (Sandbox Code Playgroud)
现在,我既不知道hash也不string是constexpr,但是这可能是周围的工作,承担他们constexpr.我想问的是,如果RTTI打开,constexpr计算哈希值的函数是否typeid(T).name()还会产生编译时常量?什么时候RTTI 关闭?
我有一个模板化的类MyClass,我想为各种参数运行它,以便测量一些值.我知道编译之前的确切参数因此我认为必须有一种方法来实现目标.
我的代码到目前为止:
template <int T>
class MyClass { /*...*/ };
constexpr int PARAMS[] = {1,2,3 /*, ...*/};
for (constexpr auto& t: PARAMS) {
MyClass<t> myClass;
// ... do sth
}
Run Code Online (Sandbox Code Playgroud)
但是编译器(gcc v4.9.2,C++ 11)不接受这一点.我也试过使用const而不是constexpr哪个也不行.
有可能是这样的吗?我真的根本不想使用宏.
我正在尝试使用constexpr编写指向成员函数的链接列表.主要是为了好玩,但它可能有一个有用的应用程序.
struct Foo;
using MethodPtr = void (Foo::*)();
struct Node
{
constexpr Node(MethodPtr method, const Node* next)
: Method(method)
, Next(next)
{}
constexpr Node Push(MethodPtr method)
{
return Node(method, this);
}
MethodPtr Method;
const Node* Next;
};
struct Foo
{
constexpr static Node GetMethods()
{
return Node{&Foo::Method1, nullptr}
.Push(&Foo::Method2)
.Push(&Foo::Method3);
}
void Method1() {}
void Method2() {}
void Method3() {}
};
int main(void)
{
constexpr Node node = Foo::GetMethods();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在调用GetMethods()时主要给出了以下错误:
const Node{MethodPtr{Foo::Method3, 0}, ((const Node*)(& Node{MethodPtr{Foo::Method2, 0}, ((const Node*)(& …Run Code Online (Sandbox Code Playgroud) 我们正在将一些代码从c ++ 03迁移到c ++ 14,并且只要有一些性能提升,我们就要使用c ++ 14特性.现在我们的一个项目中我们正在根据列名解析csv列名在一个头文件中声明,如下所示:
const string ITEM_NAME = "Item Name";
const string ITEM_ID = "Item Id";
Run Code Online (Sandbox Code Playgroud)
有这样的一百个常量,所以我想知道的是,如果我将上面的代码更改为这样的代码,是否有任何显着的性能增益:
constexpr string ITEM_NAME = "Item Name";
constexpr string ITEM_ID = "Item Id";
Run Code Online (Sandbox Code Playgroud)
由于需要将它们存储在只读存储器中,因此我们可以在二进制文件中使用constexpr的数量有任何限制吗?
编译器是否也自动优化旧的c ++ 03代码并将const变量也放在只读内存中,这种努力是不值得的?
在以下示例中,我用于static_assert验证是否foo在编译时确定.该static_assert通行证和我有一个不正确的条件下,它实际上是积极的检查.这意味着foo在编译时已知.但是,如果我使用调试器逐步执行代码,我会看到它skip_first_word也在运行时执行.
// Skip the first word in p_str
constexpr const char * skip_first_word(const char * p_str) {
return (*p_str == '\0') ? p_str :
(*p_str == ' ') ? p_str + 1 :
skip_first_word(p_str + 1);
}
// constexpr to calculate the length of a string
constexpr size_t str_len(const char * p_str) {
return (*p_str == '\0') ? 0 : str_len(p_str + 1) + 1;
}
int main()
{
constexpr …Run Code Online (Sandbox Code Playgroud) 为什么Microsoft Visual C++在编译以下代码时失败?:
template <typename T>
struct slice
{
size_t length;
T *ptr;
constexpr slice(std::initializer_list<T> list)
: length(list.size()), ptr(list.begin()) {}
};
static_assert(slice<const int>({ 1, 2, 3 }).length == 3, "!!");
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
1>test.cpp(12): error C2131: expression did not evaluate to a constant
1> visual studio 14.0\vc\include\initializer_list(50): note: failure was caused by an undefined arithmetic operation
Run Code Online (Sandbox Code Playgroud)
initializer_list所有方法的实现都标记了constexpr,看起来它对我来说应该没问题......也许它只是一个编译器问题?
我有这个片段.
#include <iostream>
#include <string>
struct JustStr {
JustStr(const std::string& x) : val(x) {}
static constexpr bool pred = false;
std::string val;
};
template <typename T>
class C {
private:
T x;
public:
C(T x_) : x(x_) {}
void f() {
if constexpr (!x.pred) {
std::cout << x.val << std::endl;
}
}
};
template<typename T>
void f2(T x) {
T y(x);
if constexpr (!y.pred) {
std::cout << x.val << std::endl;
}
}
int main() {
C<JustStr> c(JustStr("yes"));
c.f(); // Fails …Run Code Online (Sandbox Code Playgroud) 我有兴趣为个人项目创建一个非常小的constexpr容器。我需要的最重要的事情是带有真正constexpr迭代器的容器。它们最终将被添加到标准中(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0858r0.html),但是我想知道如何在当前的C ++。
假设我有一个像这样的数据结构:
template <typename T, unsigned N>
struct array {
const T data[N];
template<typename... Args>
constexpr array(const Args&... args) : data{args...} {
}
struct array_iterator {
T const* ptr;
constexpr array_iterator(const T* ptr) : ptr(ptr) {}
constexpr void operator++() { ++ptr; }
constexpr void operator--() { --ptr; }
constexpr T const& operator* () const { return *ptr; }
constexpr bool operator==(const array_iterator& rhs) const { return *(*this) == *rhs; }
constexpr bool operator!=(const array_iterator& rhs) const { …Run Code Online (Sandbox Code Playgroud) 以下代码
#include <iostream>
#include <initializer_list>
using namespace std;
constexpr initializer_list<int> list = {1, 2, 3};
template<const int* begin, const int* end>
bool contains(int v)
{
if constexpr(begin != end)
{
if (*begin = v)
return true;
else
return contains<next(begin), end>(v);
}
return false;
}
int main()
{
cout << contains<list.begin(), list.end()>(2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产生一些非常奇怪的错误消息:
main.cpp: In function 'int main()':
main.cpp:25:49: error: no matching function for call to 'contains<list.std::initializer_list<int>::begin(), list.std::initializer_list<int>::end()>(int)'
cout << contains<list.begin(), list.end()>(2);
^
main.cpp:10:6: note: candidate: 'template<const …Run Code Online (Sandbox Code Playgroud)