获取元组元素的偏移量

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

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,所以我的问题是:

  • 它是合法的C ++吗?
  • 更重要的是,为什么我可以在constexpr函数内调用std :: get(它是非constexpr)呢?
  • 就我了解constexpr而言,编译器不得不在编译时评估表达式的结果,因此在实践中不会出现零解除歧义。


    它是合法的C ++吗?

    如果通过“合法”你的意思是“良性”,那么,是的。

    如果通过“合法”,你的意思是“有效并且将在任何编译器和标准库实现上工作,那么,不,因为std::tuple不是POD。

    为什么我可以在constexpr函数中调用std::get (它不是constexpr )?

    基本上, 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);
    
    链接地址: http://www.djcxy.com/p/66589.html

    上一篇: get the offset of a tuple element

    下一篇: Why is it ill