Clang 声称“成员引用基类型 'X' 不是结构或联合”,但 X 是具有推导参数的结构模板

Clang claims that `member reference base type 'X' is not a structure or union`, but X is a structure template with deduced parameters

考虑以下代码:

template <typename T> struct X
{
    X(T) {}
    void foo() {}
};

template <typename T> struct Y
{
    int object = 0;

    void bar()
    {
        X(object).foo();
    }
};

Live on gcc.godbold.org

GCC 8.2 编译它,而 Clang 7 吐出以下错误:

<source>:13:18: error: member reference base type 'X' is not a structure or union
        X(object).foo();
        ~~~~~~~~~^~~~

这对我来说像是一个错误。

条件非常具体:如果要么结构不是模板,要么object不是成员变量,要么不涉及CTAD(class模板参数推导),那么Clang 也会编译代码。

这是怎么回事?它确实是一个 Clang 错误吗?

更重要的是,我怎样才能使代码以最少的更改编译,最好不要摆脱 CTAD?


唯一使用的标志是 -std=c++17

clang++ --version

clang version 7.0.0 (tags/RELEASE_700/final 342594)
Target: x86_64-unknown-linux-gnu
Thread model: posix

是的,这是 clang 错误,请参阅 Class template argument deduction with deduced type fails when accessing member 上面写着:

Try to compile the following c++ program:

  template <class T>
  struct C {
    C(T) {}
    int a;
  };

  template <class T>
  int foo(T v) {
    return C{v}.a; // <----
  }

  int main() {
    foo(4);
  }

The line marked above fails with the error:

error: member reference base type 'C' is not a structure or union
    return (C{v}).a;
           ~~~~~~^~

错误报告还指定了可行的案例,这些案例可能是也可能不是替代方案。

Note that the following all work fine:

  template <class T>
  C<T> foo(T v) {
    return C{v};
  }

and

int foo(int v) {
    return C{v}.a;
  }

and

  C{4}.a;

I tried this also on a recent trunk build (trunk 346600)