std::conditional 类型未知
std::conditional with unknown type
我目前正在编写一个使用 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
不可用时导致编译失败。
有更好的解决方案吗?
问得好!
来回答吧step-by-step
constexpr const bool span_builtin = // ...
有这样的东西吗?
这行得通吗?
可能不会
我们可以使用它,但问题是在 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)
我目前正在编写一个使用 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
不可用时导致编译失败。
有更好的解决方案吗?
问得好!
来回答吧step-by-step
constexpr const bool span_builtin = // ...
有这样的东西吗?
这行得通吗?
可能不会
我们可以使用它,但问题是在 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)