c++ - 获取元组元素的偏移量

标签 c++ c++11 tuples constexpr

我写了下面的代码来获取元组元素的偏移量

template<size_t Idx,class T>
 constexpr size_t tuple_element_offset() {
        return static_cast<size_t>(
                    reinterpret_cast<char*>(&std::get<Idx>(*reinterpret_cast<T*>(0))) - reinterpret_cast<char*>(0));
    }

这其实类似于offsetof宏的实现。 它看起来很丑,但在 gcc-4.6 上编译和工作正常

typedef std::tuple<int,char,long> mytuple;

mytuple var = std::make_tuple(4,'c',1000);
char * ptr = reinterpret_cast<char*>(&var);
long * pt = reinterpret_cast<long*>(ptr+tuple_element_offset<2,mytuple>());

std::cout << *pt << std::endl;

打印“1000”。

我不太了解constexpr,所以我的问题是:

  1. 它是合法的 c++ 吗?
  2. 更重要的是,为什么我可以打电话 std::get(非 constexpr) 在 constexpr 函数中?

据我了解constexpr,编译器被迫评估结果 表达式在编译时,因此在实践中不会发生零解引用。

最佳答案

Is it legal C++?

如果您所说的“合法”是指“格式良好”,那么,是的。

如果您所说的“合法”是指“有效并且适用于任何编译器和标准库实现,那么,不,因为 std::tuple 不是 POD。

Why I am allowed to call std::get (which is not constexpr) inside a constexpr function?

基本上,constexpr 函数不一定只包含常量表达式。如果您尝试在常量表达式中使用 tuple_element_offset() 函数,则会出现编译错误。

这个想法是一个函数在某些情况下可能在常量表达式中可用,但在其他情况下不可用,因此没有限制 constexpr 函数必须始终在常量表达式中可用(由于没有这样的限制,也有可能特定的 constexpr 函数可能永远无法在常量表达式中使用,就像您的函数一样)。

C++0x 草案有一个很好的例子(来自 5.19/2):

constexpr const int* addr(const int& ir) { return &ir; } // OK

// OK: (const int*)&(const int&)x is an address contant expression
static const int x = 5;
constexpr const int* xp = addr(x); 

// Error, initializer for constexpr variable not a constant expression; 
// (const int*)&(const int&)5 is not a constant expression because it takes
// the address of a temporary
constexpr const int* tp = addr(5);

关于c++ - 获取元组元素的偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5358684/

相关文章:

c++ - 从 : 引用的错误

c++ - 作为 friend 的模板参数

scala - 在标准元组上重现 HList 样式操作的无形状示例

当设置两个条件部分满足彼此而没有 IF 语句或测试组且不作为元组时,Python 正则表达式返回两个结果

c++ - 对象数组的构造函数中的随机数

c++ - 是否有一个map的find()来使用带参数的比较器?

c++ - dbus-send与QDBusAbstractInterface的对应关系

c++ - std::vector 在 push_back 期间多次调用析构函数?

c++ - 内联命名空间变量是否具有内部链接?如果不是,为什么下面的代码有效?

python - 给定一个列表和一个位掩码,我如何返回 True 索引处的值?