考虑以下C++ 11程序及其在GCC 4.7.2中的结果:
int main()
{
constexpr int i = 0;
int* p = i;
}
// g++ -g -ggdb -Wall -Wextra -pedantic -std=c++11 t.cpp
// t.cpp: In function 'int main()':
// t.cpp:4:13: error: invalid conversion from 'int' to 'int*' [-fpermissive]
// t.cpp:4:9: warning: unused variable 'p' [-Wunused-variable]
Run Code Online (Sandbox Code Playgroud)
根据标准:
[C++11: 4.10/1]:甲空指针常数是整数表达式(5.19)的整数类型的prvalue计算结果为零[..]
5.19是一个混乱,我没有完全解析它,但我们不期望i满足这个标准并充当空指针常量,因此不需要显式转换int*为初始化p?
如果我s/constexpr/const/编译-ansi而不是编译,编译成功-std=c++11.
我有一个以下结构:
struct Data
{
std::string firstMember;
std::string secondMember;
std::string thirdMember;
};
Run Code Online (Sandbox Code Playgroud)
我想按字符串名称选择其中一个成员constexpr,比如
Data instance;
auto& member = getMember(instance, "firstMember");
Run Code Online (Sandbox Code Playgroud)
getMember是constexpr函数/ struct/macros /有问题和表达式应该(我希望它)优化为简单auto& member = instance.firstMember;.我的愿望是能够getMember从另一个constexpr函数调用,而另一个函数又是特定成员的计算名称 - >某种编译时间反射.
我知道,C++中没有反射,因此可以以某种方式注册(部分特殊化?使用一些宏魔法?)有问题的struct成员名称,如:
REGISTER_MEMBER(Data, "firstMember", firstMember);
Run Code Online (Sandbox Code Playgroud)
我想要的只是编译时优化并在运行时不执行任何操作.这可能在C++ 11中如何实现?
我正在尝试实现以下内容:
#include <array>
#include <cstdint>
class Class2
{
};
class Class1
{
public:
static constexpr uint8_t GetMax() { return 5; }
static constexpr uint8_t GetMin() { return 0; }
static constexpr uint8_t GetCount() { return GetMax() - GetMin() + 1; }
private:
std::array<Class2, Class1::GetCount()> m_classes;
};
Run Code Online (Sandbox Code Playgroud)
但由于错误,我无法让它工作:
非类型模板参数不是常量表达式
我正在使用Xcode 5.0.有任何想法吗?
假设我有这样的定义类:
template<unsigned int N>
class A { ... }
Run Code Online (Sandbox Code Playgroud)
问题是如何用N迭代这些类?
for(unsigned int i = 0; i < 10; ++i) {
A<i>().doStuff();
}
Run Code Online (Sandbox Code Playgroud)
也许C++ 11中有一些新功能或者使用contrexp很酷.
接下来的问题是:如果可能的话 - 如何存储这些类?
更新 我知道它在编译时工作.假设,我有多达10个这样的全局类,它们仅在N中有所不同.例如:
A<1> first;
A<2> second;
A<42> third;
A<1034> fourth;
Run Code Online (Sandbox Code Playgroud)
并且假设,我应该称那个N比我的价值大的人.如果没有机会进行迭代,那么我必须编写长if-else结构.
void doAppropriateStuff(int value) {
if (value < 1) {
first.doStuff();
} else if (value < 2) {
second.doStuff();
} else if (value < 42) {
third.doStuff();
} else if (value < 1034) {
fourth.doStuff();
} else {
...
}
} …Run Code Online (Sandbox Code Playgroud) 此代码有效:
struct Blob {
static constexpr int a = 10;
};
int main() {
Blob b;
auto c = b.a;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我改为int,float我会收到一个错误:
struct Blob {
static constexpr float a = 10.0f;
};
Run Code Online (Sandbox Code Playgroud)
/tmp/main-272d80.o:在函数
main': main.cpp:(.text+0xe): undefined reference toBlob :: a'中
为什么我不能constexpr float以这种方式使用?
编译器:Ubuntu clang版本3.5.0-4ubuntu2(标签/ RELEASE_350/final)
在gcc版本4.9.1(Ubuntu 4.9.1-16ubuntu6)上测试并且没有错误.
编辑:
如果我使用-O1,-O2,-O3或-Os但它会在-O0失败时进行编译
在C++ 11或C++ 14中,我试图为constexpr函数定义一个类型别名.
我试过了:
#include <iostream>
constexpr int foo(int i, int j) { return i + j; }
using TConstExprFunction = constexpr int (*)(int i, int j);
int main() {
TConstExprFunction f = foo;
constexpr int i = f(1, 2);
std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
但它无法用g ++和clang ++编译.
克++:
error: expected type-specifier before 'constexpr'
铛++:
error: type name does not allow constexpr specifier to be specified
我必须按照以下方式进行编译
#include <iostream>
constexpr int foo(int i, int j) { return i + …Run Code Online (Sandbox Code Playgroud) 我试图基于一个整数数组创建一个简单的 LookUpTable,其思路是在编译时计算它.
试图使它可以用于我可能拥有的各种整数类型的任何其他未来表,我需要它作为模板.
所以我有一个LookUpTable.h
#ifndef LOOKUPTABLE_H
#define LOOKUPTABLE_H
#include <stdexcept> // out_of_range
template <typename T, std::size_t NUMBER_OF_ELEMENTS>
class LookUpTableIndexed
{
private:
//constexpr static std::size_t NUMBER_OF_ELEMENTS = N;
// LookUpTable
T m_lut[ NUMBER_OF_ELEMENTS ] {}; // ESSENTIAL T Default Constructor for COMPILE-TIME INTERPRETER!
public:
// Construct and Populate the LookUpTable such that;
// INDICES of values are MAPPED to the DATA values stored
constexpr LookUpTableIndexed() : m_lut {}
{
//ctor
}
// Returns the …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用编译时生成的数组来实现快速函数调度程序,以便能够在运行时在O(1)中使用它.
一些代码行只是为了澄清:
template<int i>
void f()
{
// do stuff
}
// specialized for every managed integer
template<>
void f<1>
{
// do stuff
}
Dispatcher<1,5,100,300> dispatcher;
dispatcher.execute(5); // this should call f<5>()
Run Code Online (Sandbox Code Playgroud)
我们将调度器的输入数量(在这种情况下为4)调用N,并且在这种情况下调度调度器输入(300)的最大值.
我已经能够创建一个大小等于M的数组.这利用了这样一个事实:在运行时你可以做类似的事情:
dispatcher.execute(5) -> internalArray[5]();
Run Code Online (Sandbox Code Playgroud)
这当然是有效的,但对于大尺寸的阵列来说这是不可行的.
最好的方法是仅生成N个元素的数组,并做一些数学技巧将输入索引转换为第二个数组的索引.
在这个例子中,将1,5,100,300分别转换为0,1,2,3.我已经能够做一种预处理方法来改造它们,但我正在寻找一种避免这一步骤的方法.
换句话说,我认为我正在寻找某种最小的完美散列,可以在编译时以非常有效的方式用于我的特定情况(理想情况下没有任何开销,例如:goto:MyInstruction).
我不是在寻找使用虚函数,std :: map或复杂操作的替代方法.
请问是否有不清楚的事情.
PS我正在使用C++ 11,但任何想法都是受欢迎的
[编辑]我知道标签是GCC的语言扩展值.有了这些我可能能够实现我的目标,但需要一个便携式解决方案.
请考虑以下代码:
template <int N, typename T> void f(T) { }
template <typename T>
constexpr int k(T&) { return 0; }
int main()
{
constexpr auto i = 1;
f<k(i)>([&i]
{
f<k(i)>(0);
});
}
Run Code Online (Sandbox Code Playgroud)
clang++ (主干)编译它.g++ (trunk)因以下错误而失败:
Run Code Online (Sandbox Code Playgroud)<source>: In lambda function: <source>:11:19: error: no matching function for call to 'f<k<const int>((* & i))>(int)' 11 | f<k(i)>(0); | ^ <source>:1:35: note: candidate: 'template<int N, class T> void f(T)' 1 | template <int N, typename T> void f(T) { } …
假设我有一些假设的结构:
struct X {
int i;
double d;
}
Run Code Online (Sandbox Code Playgroud)
然后我可以写
constexpr X x_c_array[]{{5, 6.3}};
Run Code Online (Sandbox Code Playgroud)
要么
constexpr std::initializer_list<X> x_ilist{{5, 6.3}};
Run Code Online (Sandbox Code Playgroud)
auto不可能使用-编译器必须知道内部类型。
这两个版本都有缺点吗?
更新:
同样值得关注的是,您是否能够使用/将一种类型转换为另一种类型-例如。在构造标准容器时?
c++ ×10
constexpr ×10
c++11 ×5
templates ×3
c++17 ×2
clang ×2
c++14 ×1
perfect-hash ×1
type-alias ×1