简体   繁体   English

std::conditional 未知类型

[英]std::conditional with unknown type

I'm currently writing a library which makes use of C++20's std::span .我目前正在编写一个使用 C++20 的std::span的库。 Compiler library support for std::span is at this point rather scarce.编译器库对std::span的支持在这一点上相当稀少。 Therefore, I have a marco which allows to use a 3rd-party implementation instead (in my case tcb::span ).因此,我有一个允许使用第 3 方实现的 marco(在我的例子中是tcb::span )。 The macro looks like this:宏看起来像这样:

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

Usage through the library looks like this:通过库的用法如下所示:

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

This is not pretty at all.这一点都不漂亮。 I was looking for a better solution and I came across std::conditional which I have already used in the past.我正在寻找一个更好的解决方案,我遇到了我过去已经使用过的std::conditional A naive attempt would looks like this:天真的尝试看起来像这样:

constexpr const bool span_builtin = // ...

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

Which would result in usage like this:这将导致这样的用法:

void my_func(const span_type& s);

The problem lies in the fact that std::span is an unknown type at compile time when std::span is not available which makes compilation fail.问题在于,当std::span不可用时,std:: std::span在编译时是未知类型,这会导致编译失败。

Is there a nicer solution to this?有更好的解决方案吗?

Nice question!好问题!

Let's answer it step-by-step让我们一步步来回答

constexpr const bool span_builtin = // ...

Does something like this exist?这样的东西存在吗?

Would this work?这行得通吗?

Probably not可能不会

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

We could use this but the issue with this is that below C++20, Span would not be defined我们可以使用它,但问题是在 C++20 以下,Span 不会被定义

Also we cannot officially add our own span Forward Declaration to std namespace我们也不能正式将我们自己的 span Forward Declaration 添加到 std 命名空间

So what's the solution?那么解决方案是什么?

The solution would end up being very similar to yours该解决方案最终将与您的非常相似

#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
}

See also Proper way to define type (typedef vs #define)另请参阅定义类型的正确方法(typedef vs #define)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM