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

Hol*_*Cat 8 c++ clang compiler-bug template-argument-deduction c++17

考虑以下代码:

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

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

    void bar()
    {
        X(object).foo();
    }
};
Run Code Online (Sandbox Code Playgroud)

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();
        ~~~~~~~~~^~~~
Run Code Online (Sandbox Code Playgroud)

对我来说这看起来像个错误.

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

这里发生了什么?它确实是一个Clang bug吗?

更重要的是,如何在没有摆脱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
Run Code Online (Sandbox Code Playgroud)

Sha*_*our 7

是的,这是clang bug看到类模板参数推断与推导类型在访问成员时失败说:

尝试编译以下c ++程序:

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

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

  int main() {
    foo(4);
  }
Run Code Online (Sandbox Code Playgroud)

上面标记的行失败并显示错误:

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

错误报告还指定了有效的案例,这些案例可能是也可能不是替代案例.

请注意,以下所有工作正常:

  template <class T>
  C<T> foo(T v) {
    return C{v};
  }
Run Code Online (Sandbox Code Playgroud)

int foo(int v) {
    return C{v}.a;
  }
Run Code Online (Sandbox Code Playgroud)

  C{4}.a;
Run Code Online (Sandbox Code Playgroud)

我也尝试了最近的主干版本(trunk 346600)