Bia*_*sta 7 c++ templates sfinae c++17 void-t
使用SFINAE,我需要检测容器的某些属性。
例如:
#include <type_traits>
#include <vector>
template <typename Container, typename = void>
struct Trait {};
template <typename Container>
struct Trait<
Container,
std::enable_if_t<std::is_integral_v<typename Container::value_type>>> {
static constexpr bool foo = false;
};
template <typename Container>
struct Trait<
Container,
std::enable_if_t<std::is_floating_point_v<typename Container::value_type>>> {
static constexpr bool foo = true;
};
static_assert(Trait<std::vector<int>>::foo == false);
static_assert(Trait<std::vector<double>>::foo == true);
Run Code Online (Sandbox Code Playgroud)
上面的代码可以按预期进行编译和运行(在clang和gcc上)。在这里检查。
但是,如果我稍加修改将模板类型包装在里面的代码std::void_t
:
template <typename Container>
struct Trait<
Container,
std::void_t<std::enable_if_t<std::is_integral_v<typename Container::value_type>>>> {
static constexpr bool foo = false;
};
template <typename Container>
struct Trait<
Container,
std::void_t<std::enable_if_t<std::is_floating_point_v<typename Container::value_type>>>> {
static constexpr bool foo = true;
};
Run Code Online (Sandbox Code Playgroud)
然后,它可以在gcc上工作并编译,但是在clang上被拒绝。在这里检查。
特别是,铛埋怨redifinition的Trait
。
问题(关于第二版代码):
1)这是一个叮当响的 bug吗?
2)如果clang是标准投诉(例如,它是gcc错误),为什么添加std::void_t
会重新定义Trait
?我希望SFINAE会阻止重新定义。