【问题标题】:std::conditional with unknown type具有未知类型的 std::conditional
【发布时间】:2021-01-08 00:02:48
【问题描述】:

我目前正在编写一个使用 C++20 的 std::span 的库。对std::span 的编译器库支持目前相当稀缺。因此,我有一个允许使用第 3 方实现的 marco(在我的情况下为 tcb::span)。宏如下所示:

#ifdef SPAN_BUILTIN
#   include <span>
#   define SPAN std::span
#else
#   include "3rdparty/span.hpp"
#   define SPAN tcb::span
#endif

通过库的用法如下:

void my_func(const SPAN<int>& s);

这一点都不漂亮。我一直在寻找更好的解决方案,但遇到了我过去已经使用过的std::conditional。一个天真的尝试看起来像这样:

constexpr const bool span_builtin = // ...

template <class T>
using span_type = typename std::conditional<span_builtin, std::span<T>, tcb::span<T>>::type;

这会导致这样的用法:

void my_func(const span_type& s);

问题在于std::span在编译时是未知类型,而std::span不可用导致编译失败。

有没有更好的解决方案?

【问题讨论】:

  • 为什么不在std 命名空间中声明一个名为span 的别名,编写简单引用std::span 的代码,然后在更新编译器时删除别名?跨度>
  • # define SPAN std::span 更改为template &lt;typename T&gt; using span = std::span&lt;T&gt;;。同时对第三方库行进行相应的更改。
  • 为什么不到处使用tcb::span?这将节省大量的调试工作。
  • @SamVarshavchik:那将是未定义的行为,并破坏存在 std::span 实现但尚未符合标准的编译器。

标签: c++ c++20 std-span


【解决方案1】:

好问题!

让我们一步一步回答它

constexpr const bool span_builtin = // ...

这样的东西存在吗?

这行得通吗?

应该不会

https://stackoverflow.com/a/45594334/1691072

我们可以使用这个,但问题是在 C++20 以下,Span 不会被定义

Also we cannot officially add our own span Forward Declaration to std namespace

那么解决办法是什么?

解决方案最终会与您的非常相似

#include <type_traits>

#if __cplusplus > 201703L // Do something else for MSVC if you cannot use `/Zc:__cplusplus`
#include <span>
template<typename T, std::size_t N = std::dynamic_extent>
using span = std::span<T, N>;
#else
template<typename T>
using span = tcb::span<T>;
#endif

int main ()
{
#if __cplusplus > 201703L
   static_assert(std::is_same_v< span<int>, std::span<int>>);
#else
   static_assert(std::is_same_v< span<int>, tcb::span<int>>);
#endif
}

另见Proper way to define type (typedef vs #define)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    相关资源
    最近更新 更多