(BE)(NFC): Use much more specific CPP feature flags (#6150)
diff --git a/include/pybind11/complex.h b/include/pybind11/complex.h
index a6ec11a..9d0812f 100644
--- a/include/pybind11/complex.h
+++ b/include/pybind11/complex.h
@@ -27,7 +27,7 @@
     static std::string format() { return std::string(value); }
 };
 
-#ifndef PYBIND11_CPP17
+#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
 
 template <typename T>
 constexpr const char
diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h
index 740001d..c8fff5c 100644
--- a/include/pybind11/detail/common.h
+++ b/include/pybind11/detail/common.h
@@ -1202,7 +1202,7 @@
     static std::string format() { return std::string(1, c); }
 };
 
-#if !defined(PYBIND11_CPP17)
+#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
 
 template <typename T>
 constexpr const char
@@ -1278,7 +1278,7 @@
 PYBIND11_NAMESPACE_END(detail)
 
 // overload_cast requires variable templates: C++14
-#if defined(PYBIND11_CPP14)
+#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304L
 #    define PYBIND11_OVERLOAD_CAST 1
 /// Syntax sugar for resolving overloaded function pointers:
 ///  - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)
@@ -1292,7 +1292,8 @@
 ///  - sweet:   overload_cast<Arg>(&Class::func, const_)
 static constexpr auto const_ = std::true_type{};
 
-#if !defined(PYBIND11_CPP14) // no overload_cast: providing something that static_assert-fails:
+#if !defined(__cpp_variable_templates) || __cpp_variable_templates < 201304L
+// No overload_cast: providing something that static_assert-fails.
 template <typename... Args>
 struct overload_cast {
     static_assert(detail::deferred_t<std::false_type, Args...>::value,
diff --git a/include/pybind11/detail/init.h b/include/pybind11/detail/init.h
index a1083f8..5f9e925 100644
--- a/include/pybind11/detail/init.h
+++ b/include/pybind11/detail/init.h
@@ -388,7 +388,7 @@
     // instance, or the alias needs to be constructible from a `Class &&` argument.
     template <typename Class, typename... Extra>
     void execute(Class &cl, const Extra &...extra) && {
-#if defined(PYBIND11_CPP14)
+#if defined(__cpp_init_captures) && __cpp_init_captures >= 201304L
         cl.def(
             "__init__",
             [func = std::move(class_factory)]
@@ -435,7 +435,7 @@
         static_assert(Class::has_alias,
                       "The two-argument version of `py::init()` can "
                       "only be used if the class has an alias");
-#if defined(PYBIND11_CPP14)
+#if defined(__cpp_init_captures) && __cpp_init_captures >= 201304L
         cl.def(
             "__init__",
             [class_func = std::move(class_factory), alias_func = std::move(alias_factory)]
@@ -524,7 +524,7 @@
     void execute(Class &cl, const Extra &...extra) && {
         cl.def("__getstate__", std::move(get), pos_only());
 
-#if defined(PYBIND11_CPP14)
+#if defined(__cpp_init_captures) && __cpp_init_captures >= 201304L
         cl.def(
             "__setstate__",
             [func = std::move(set)]
diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h
index eebb130..f57514a 100644
--- a/include/pybind11/pybind11.h
+++ b/include/pybind11/pybind11.h
@@ -294,7 +294,7 @@
 
 // Prior to C++17, we don't have inline variables, so we have to
 // provide an out-of-line definition of the class member.
-#if !defined(PYBIND11_CPP17)
+#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
 template <typename cast_in, typename cast_out>
 constexpr typename ReadableFunctionSignature<cast_in, cast_out>::sig_type
     ReadableFunctionSignature<cast_in, cast_out>::kSig;
diff --git a/tests/test_class.cpp b/tests/test_class.cpp
index 84efb80..e520f29 100644
--- a/tests/test_class.cpp
+++ b/tests/test_class.cpp
@@ -516,7 +516,8 @@
     py::class_<StringWrapper>(m, "StringWrapper").def(py::init<std::string>());
     py::implicitly_convertible<std::string, StringWrapper>();
 
-#if defined(PYBIND11_CPP17)
+#if (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606L)                                  \
+    || (defined(__INTEL_COMPILER) && __cplusplus >= 201703L)
     struct alignas(1024) Aligned {
         std::uintptr_t ptr() const { return (uintptr_t) this; }
     };