模板化转换运算符类型推导在 clang 和 gcc 中不同

templated conversion operator type deduction differs in clang and gcc

在过去的几天里,我一直在与编译器之间在模板化转换运算符类型推导方面的差异作斗争,我终于将至少一个差异归结为一个堆栈溢出大小的示例:

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 { };

Demo

表达式 detect_call<decltype(foo)>::value 在 clang 中给出 true,在 gcc 中给出 false(使用我可以使用的任一编译器的任何现代版本,最新版本是 gcc 5.2 和铿锵声 3.8)。问题:

注意:这似乎与这个问题类似:(事实上,我也 运行 了解了那个确切的区别),但我不太明白两者之间的映射那个答案和这个案例。如果这只是这个问题的另一个实例,那么这个问题归结为如何将该问题映射到这个用例中。

这可以简化为实际调用 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 错误(#63217 per TC's comment above). Per [temp.deduct.conv],这应该将 T 推断为 int,因为引用和限定符都应该被删除(在这种情况下 Pconst T&Aint).