过去几天我一直在努力解决编译器之间关于模板化转换运算符类型推导的差异,并且我最终将至少一个差异归结为堆栈溢出大小的示例:
final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
if(passwordEncoder.matches(rawPassword, encodedPassword)){
return true;
else{
return false;
}
表达式void foo(int i);
struct any_const_reference {
template <typename T>
operator const T&();
};
template <typename T, typename Enable=void>
struct detect_call : std::false_type { };
template <typename T>
struct detect_call<T,
decltype( declval<T>()( any_const_reference() ) )
> : std::true_type { };
在clang中提供detect_call<decltype(foo)>::value
,在gcc中提供true
(使用我可以获得的任何编译器的任何现代版本,最新的是gcc 5.2和clang 3.8 )。问题:
false
)中应用于T
的类型推导规则是什么,以及它们在C ++标准? 注意:这似乎与这个问题类似:Template argument type deduction by conversion operator(事实上,我也遇到了这个确切的差异),但我还没有看到答案之间的映射和这个案子。如果这只是此问题的另一个实例,那么这个问题归结为如何将该问题映射到此用例。
答案 0 :(得分:4)
这可以简化为实际调用foo()
:
void foo(int ) { }
struct any_const_reference {
template <typename T>
operator const T&();
};
int main() {
foo(any_const_reference{}); // ok on clang
// error on gcc
}
这是一个gcc错误(上面根据TC的评论#63217)。根据{{3}},这应该将T
推断为int
,因为应删除引用和限定符(在这种情况下,P
为const T&
和{{1} }是A
)。