std :: launder alternative pre c ++ 17

bal*_*lki 11 c++ language-lawyer c++14 c++17 stdlaunder

它就像std::optional,但不存储额外的布尔.用户必须确保仅在初始化后访问.

template<class T>
union FakeOptional { //Could be a normal struct in which case will need std::aligned storage object.
    FakeOptional(){}  //Does not construct T
    template<class... Args>
    void emplace(Args&&... args){
        new(&t) T{std::forward<Args&&>(args)...};
    }
    void reset(){
        t.~T();
    }
    operator bool() const {
        return true;
    }
    constexpr const T* operator->() const {
        return std::launder(&t);

    }
    constexpr T* operator->() {
        return std::launder(&t);
    }
    T t;
};
Run Code Online (Sandbox Code Playgroud)

如果您想知道为什么我需要这样一个模糊的数据结构,请点击此处:https://gitlab.com/balki/linkedlist/tree/master

  1. 可以忽略std::launder吗?我猜不会.
  2. 由于std::launder仅在c ++ 17中可用,如何在c ++ 14中实现上面的类?boost::optional并且std::experimental::optional应该需要类似的功能还是他们使用编译器特定的魔法?

注意:很容易遗漏,类型被声明为union.这意味着构造函数T真的没有被调用.参考:https://gcc.godbolt.org/z/EVpfSN

xsk*_*xzr 4

不,你不能。std::launder提出的原因之一是它std::optional无法在 C++14 中实现。详细可以参考这个讨论。

另一方面,您可以在不使用constexpr. 这个想法是使用缓冲区,reinterpret_cast因为 的结果reinterpret_cast将始终引用新创建的对象(在 C++17 中std::launder仍然需要,但在 C++14 中这很好)。例如,

template<class T>
struct FakeOptional { 
    FakeOptional(){}  
    template<class... Args>
    void emplace(Args&&... args){
        new(&storage) T{std::forward<Args&&>(args)...};
    }
    void reset(){
        reinterpret_cast<T*>(&storage)->~T();
    }
    operator bool() const {
        return true;
    }
    const T* operator->() const {
        return reinterpret_cast<const T*>(&storage);
    }
    T* operator->() {
        return reinterpret_cast<T*>(&storage);
    }
    std::aligned_storage_t<sizeof(T), alignof(T)> storage;
};
Run Code Online (Sandbox Code Playgroud)

的实现就是boost::optional 利用了这个思想,并没有实现语义(具体constexpr可以参考其源码)。

  • @Oliv 当然,我的方法只有在语言律师的方式中才是必要的。const/ref 成员的限制[在 C++03 中添加](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#89),因此一些旧代码可能会中断如果启用此类优化。我想,这就是这些编译器有点保守的原因之一。 (2认同)