英文:
How to work around "function template has already been defined" when using std::enable_if with constexpr method
问题
当在std::enable_if_t
的参数中使用constexpr
方法时,旧版MSVC编译器会报告“函数模板已经定义”的错误。G++和较新版本的MSVC编译器会接受此代码。如何使旧版MSVC编译器也能正常工作?
示例代码:
#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;
}
在Compiler Explorer上查看:https://godbolt.org/z/15PnPhvo8。MSVC 19.14拒绝此代码,MSVC 19.33接受它。为什么旧版编译器拒绝该代码?
英文:
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?
答案1
得分: 2
你可以使用 std::enable_if_t
作为模板参数代替:
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;
}
英文:
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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论