我有以下特征来检测两个类型是否可以被整除,并返回结果操作类型或另一个 Default
类型:
struct default_t { };
// Overloaded template for fallbacks
template <class U, class V>
default_t operator/(U, V);
// If the expression std::declval<U>()/std::declval<V>() is valid,
// gives the return type, otherwize provide Default.
template <class U, class V, class Default>
struct div_type_or {
using type_ = decltype(std::declval<U>() / std::declval<V>());
using type = typename std::conditional<
std::is_same<type_, default_t>{},
Default,
type_>::type;
};
template <class... Args>
using div_type_or_t = typename div_type_or<Args...>::type;
当我尝试使用不可分割的 std::chrono::duration
类型时,这适用于libstdc,但不适用于libc,例如:
struct A { };
div_type_or_t<std::chrono::seconds, A, int> b;
我收到以下错误:
/ Library / Developer / CommandLineTools / usr / include / c / v1 / chrono:764:81:错误:'std :: __ 1 :: common_type'typename中没有名为'type'的类型common_type :: type> :: value> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~ ^ ~~~ / Library / Developer / CommandLineTools / usr / include / c / v1 / chrono:777:7:注意:在实例化'duration_divide_imp>的默认参数时,需要A>': duration_divide_imp,_Rep2 > ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~> / Library / Developer / CommandLineTools / usr / include / c / v1 / chrono:784:10:注意:在模板类'std :: __ 1 :: chrono :: __ duration_divide_result>的实例化中,A,false >'在这里请求typename __duration_divide_result,_Rep2> :: type ^ test.cpp:16:46:注意:同时将推导出的模板参数替换为函数模板'operator /'[with _Rep1 = long long,_Period = std :: __ 1 ::比率<1,1>,Rep2 = A]使用type = decltype(std :: declval()/ std :: declval()); ^ test.cpp:24:1:注意:在模板类'div_type_or>的实例化中,A,D>'在这里使用div_type_or_t = typename div_type_or :: type; ^ test.cpp:48:19:注意:在实例化模板类型别名'div_type_or_t'时请求div_type_or_t,D> {},“”);
据我了解,这是因为 operator/
的 operator/
的以下重载失败:
template< class Rep1, class Period, class Rep2 >
duration<typename std::common_type<Rep1,Rep2>::type, Period>
constexpr operator/( const duration<Rep1, Period>& d,
const Rep2& s );
我认为,因为 std::common_type
是函数签名的一部分,这将允许SFINAE工作并使用 operator/
的自定义重载,从而推导出 default_t
,但显然这不起作用......
由于这适用于libstdc,我只是想知道我的代码是否存在问题(也许我不理解SFINAE在这种情况下的工作方式)或者这是否是一个libc错误?
1 回答
在libc中,我们有:
所以而不是
std::common_type<_Rep1, _Rep2>::type
,他们用
__duration_divide_result<duration<_Rep1, _Period>, _Rep2 /*, false*/>
,实例化
__duration_divide_imp<duration<_Rep1, _Period>, _Rep2 /*, is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value*/>
这种用法是一个很难的错误 .
我想说libc中的实现在这方面是不正确的 .