When using a constexpr
method as the argument of std::enable_if_t
, old MSVC compilers complain about "function template has already been defined". G++ and newer MSVC compilers accept that. How I can make that work also with old MSCV compilers?
Example code:
#include <climits>
#include <iostream>
#include <type_traits>
template <typename NumberType>
constexpr auto doBitCountsMatch(const int f_bitCount) -> bool {
return (static_cast<int>(CHAR_BIT * sizeof(NumberType)) == f_bitCount);
}
template <typename NumberType, int bitCount>
auto test()
-> std::enable_if_t<doBitCountsMatch<NumberType>(bitCount), NumberType> {
std::cout << "Bit counts match." << std::endl;
return 0;
}
template <typename NumberType, int bitCount>
auto test()
-> std::enable_if_t<!doBitCountsMatch<NumberType>(bitCount), NumberType> {
std::cout << "Bit counts don't match." << std::endl;
return 0;
}
int main() {
int number = 0;
test<decltype(number), 32>();
return 0;
}
And here in Compiler Explorer: https://godbolt.org/z/15PnPhvo8: MSVC 19.14 rejects the code, MSVC 19.33 accepts it. Why do the old compilers reject the code?
You might use std::enable_if_t
as template parameter instead:
template <typename NumberType, int bitCount,
std::enable_if_t<doBitCountsMatch<NumberType>(bitCount), int> = 0>
auto test() -> NumberType
{
std::cout << "Bit counts match." << std::endl;
return 0;
}
template <typename NumberType, int bitCount,
std::enable_if_t<!doBitCountsMatch<NumberType>(bitCount), int> = 0>
auto test() -> NumberType
{
std::cout << "Bit counts don't match." << std::endl;
return 0;
}