patterncppModerate
Seamlessly migrating <experimental/optional> to <optional>
Viewed 0 times
seamlesslyoptionalmigratingexperimental
Problem
From this Stack Overflow answer, I learned that C++17 will have
[make] migrating from experimental to std almost seamless
This still leaves the question of how to do it. Doing something like
optional.h demonstration on coliru
__has_include, which can [make] migrating from experimental to std almost seamless
This still leaves the question of how to do it. Doing something like
namespace std { using namespace std::experimental; } is undefined behaviour, so I came up with this method:optional.h demonstration on coliru
#pragma once
#if __has_include()
# include
# define HAS_STD_OPTIONAL
#elif __has_include()
# include
# define HAS_STD_EXPERIMENTAL_OPTIONAL
#else
# error Must have an optional type, either from or if not supported from .
#endif
#if defined HAS_STD_OPTIONAL
namespace opt {
template
using optional = std::optional;
using bad_optional_access = std::bad_optional_access;
using nullopt_t = std::nullopt_t;
using in_place_t = std::in_place_t;
constexpr auto nullopt = std::nullopt;
constexpr auto in_place = std::in_place;
template
constexpr auto make_optional(T && value)
{
return std::make_optional(std::forward(value));
}
}
#elif defined HAS_STD_EXPERIMENTAL_OPTIONAL
namespace opt {
template
using optional = std::experimental::optional;
using bad_optional_access = std::experimental::bad_optional_access;
using nullopt_t = std::experimental::nullopt_t;
using in_place_t = std::experimental::in_place_t;
constexpr auto nullopt = std::experimental::nullopt;
constexpr auto in_place = std::experimental::in_place;
template
constexpr auto make_optional(T && value)
{
return std::experimental::make_optional(std::forward(value));
}
}
#endifSolution
A modification of @Jerry's answer:
this has the advantage that the same namespace can be used for all "experimental" features (
So
We have to only
#pragma once
#if __has_include()
# include
namespace stdx {
using namespace ::std;
}
#elif __has_include()
# include
namespace stdx {
using namespace ::std;
using namespace ::std::experimental;
}
#else
# error and not found
#endifthis has the advantage that the same namespace can be used for all "experimental" features (
stdx).So
stdx::optional and stdx::variant both work.We have to only
using namespace ::std::experimental; after at least one <experimental/ header is included, as if it does not exist that is ill formed, and introducing one ourselves also makes the program ill formed.Code Snippets
#pragma once
#if __has_include(<optional>)
# include <optional>
namespace stdx {
using namespace ::std;
}
#elif __has_include(<experimental/optional>)
# include <experimental/optional>
namespace stdx {
using namespace ::std;
using namespace ::std::experimental;
}
#else
# error <experimental/optional> and <optional> not found
#endifContext
StackExchange Code Review Q#136350, answer score: 13
Revisions (0)
No revisions yet.