Seamlessly migrating  to From this Stack Overflow answer, I learned that C++17 will have __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(&lt;optional&gt;)
#   include &lt;optional&gt;
#   define HAS_STD_OPTIONAL
#elif __has_include(&lt;experimental/optional&gt;)
#   include &lt;experimental/optional&gt;
#   define HAS_STD_EXPERIMENTAL_OPTIONAL
#else
#   error Must have an optional type, either from &lt;optional&gt; or if not supported from &lt;experimental/optional&gt;.
#endif

#if defined HAS_STD_OPTIONAL

namespace opt {
    template&lt;class T&gt;
    using optional = std::optional&lt;T&gt;;
    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&lt;class T&gt;
    constexpr auto make_optional(T &amp;&amp; value)
    {
        return std::make_optional(std::forward&lt;T&gt;(value));
    }
}

#elif defined HAS_STD_EXPERIMENTAL_OPTIONAL

namespace opt {
    template&lt;class T&gt;
    using optional = std::experimental::optional&lt;T&gt;;
    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&lt;class T&gt;
    constexpr auto make_optional(T &amp;&amp; value)
    {
        return std::experimental::make_optional(std::forward&lt;T&gt;(value));
    }
}

#endif
A modification of @Jerry's answer:

#pragma once

#if __has_include(&lt;optional&gt;)

#   include &lt;optional&gt;
namespace stdx {
  using namespace ::std;
}
#elif __has_include(&lt;experimental/optional&gt;)
#   include &lt;experimental/optional&gt;
namespace stdx {
  using namespace ::std;
  using namespace ::std::experimental;
}

#else
#   error &lt;experimental/optional&gt; and &lt;optional&gt; not found
#endif


this 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 &lt;experimental/ header is included, as if it does not exist that is ill formed, and introducing one ourselves also makes the program ill formed.