c++templateslanguage-lawyerimplicit-conversionnon-type

Should implicit conversion work in the context of a template argument?


To be more explicit, should a compiler treat a true_type value as true in the first argument of enable_if, because true_type is really std::integral_constant<bool, true>, and integral_constant defines the type conversion function operator value_type?

The following is the simplest test code:

#include <type_traits>

template <typename T>
std::enable_if_t<std::is_pod<T>{}>
test(T)
{
}

int main()
{
    test(true);
}

It is accepted by GCC and Clang, but rejected by MSVC (up to Visual Studio 2019 v16.3.1).


Solution

  • Your code is well-formed, converted constant expression should be considered for non-type template parameter.

    The template argument that can be used with a non-type template parameter can be any converted constant expression of the type of the template parameter.

    A converted constant expression of type T is an expression implicitly converted to type T, where the converted expression is a constant expression, and the implicit conversion sequence contains only:

    • constexpr user-defined conversions (so a class can be used where integral type is expected)

    The conversion operator of std::is_pod inherited from std::integral_constant is constexpr user-defined conversions, then the converted bool from std::is_pod is converted constant expression and could be applied.


    As the workaround (I suppose you've realized) you can use std::is_pod_v<T> (since C++17) or std::is_pod_v<T>::value instead.