I am currently struggling with Visual Studio 2017 (compilation using /std:c++latest , if such help).
In the code under consideration, a structured specialization is simply selected based on the result of some constexpr template function. GCC and clang have no problem compiling it.
Here is my MCVE:
#include <type_traits> struct A { enum { test_trait = true }; }; template<typename T> constexpr int choose() { return T::test_trait; } template<typename T, typename Enable=void> struct Chosen; template<typename T> struct Chosen<T, std::enable_if_t<choose<T>() == 1>> {}; void foo() { // This works constexpr int chosen = choose<A>(); static_assert(chosen == 1, ""); // This resolves to the undefined struct. using Chosen_t = Chosen<A>; Chosen_t x; (void)x; }
choose() is actually more complex in my code base, but static_assert is still compiling and checking perfectly.
I suggested that if static_assert compiles, there is no reason for enable_if not be able to do its magic. Am I mistaken? I think "maybe" T not a technically dependent type of enable_if ... But if that were the case, I would expect GCC and a clang to hit my wrist.
I can get around this by wrapping the choose() result in std::integral_constant , for example:
template<typename T> struct Chooser : public std::integral_constant<int, choose<T>()> {}; template<typename T> struct Chosen<T, std::enable_if_t<Chooser<T>::value>> {};
But I really would not have to jump through this hoop.
Should template resolution resolve this the way I expect? I'm worried that the code is actually wrong, and GCC and clang are just condescending to me.
c ++ visual-studio c ++ 14 enable-if constexpr
Frank
source share