代码之家  ›  专栏  ›  技术社区  ›  HolyBlackCat

clang声明“member-reference-base-type”x不是结构或联合类型,但x是具有推导参数的结构模板

  •  8
  • HolyBlackCat  · 技术社区  · 7 年前

    考虑以下代码:

    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(类模板参数推导),那么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
    
    1 回复  |  直到 7 年前
        1
  •  6
  •   Shafik Yaghmour    7 年前

    是的,这是叮当虫,看 Class template argument deduction with deduced type fails when accessing member 上面写着:

    尝试编译以下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);
      }
    

    上面标记的行失败,错误为:

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

    bug报告还指定了可以工作的案例,这些案例可能是或者不是替代方案。

    请注意,以下各项工作正常:

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

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

      C{4}.a;
    

    我也在最近的一个主干构建(主干346600)上尝试过这个方法。