[英]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.