gcc 对函数参数的成员函数的调用可以用作模板参数吗?

brgchamk  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(137)
#include <type_traits>

template<class T>
auto f(T x) -> std::enable_if_t<x.size() == 4>;

对Clang和MSVC有效,但对GCC无效。哪个是正确的?https://godbolt.org/z/q8v4G5vn6

sg2wtvxw

sg2wtvxw1#

是的,上面的代码是格式良好的,这是你找到的GCC bug 80242的一个示例。
x依赖于T的类型,x.size()可以是某些x的常量表达式。在示例化f之前,编译器不应将此代码视为格式错误,因为x.size()可能是一个常量表达式。
即使x是一个在编译时不存在的对象,我们也可以访问它的大小:

std::array<int, 10> x;
constexpr std::size_t size = x.size();

......所有主要的编译器都接受这一点,他们应该这样做。之所以可以这样写,是因为std::array.size()永远不会访问对象x的值或地址,只访问std::array给定的模板参数。这意味着在你的函数中,如果T = std::array<...>,那么x.size()是一个常量表达式,应该可以用作std::enable_if_t的模板参数。
GCC的错误输出也是完全没有意义的,这进一步强化了这是一个编译器错误的想法:

<source>:5:46: error: template argument 1 is invalid
    5 | auto f(T x) -> std::enable_if_t<x.size() == 4>;
      |                                              ^
<source>:5:46: error: template argument 1 is invalid
<source>:5:46: error: template argument 1 is invalid
<source>:5:46: error: template argument 1 is invalid
<source>:5:46: error: template argument 1 is invalid
<source>:5:16: error: invalid use of template-name 'std::enable_if_t' without an argument list
    5 | auto f(T x) -> std::enable_if_t<x.size() == 4>;
      |                ^~~

相关问题