【问题标题】:error of template instantiation of ref-qualified members引用限定成员的模板实例化错误
【发布时间】:2016-07-08 13:22:29
【问题描述】:
#include <iostream>
using std::cout;


template<typename T>
class A{
  public:
  template<typename U>
  void f(U const&)  & ;
  template<typename U>
  void f(U const&) && ;
};


  template<typename T>
  template<typename U>
   void A<T>::f(U const& x)  & { std::cout << "lvalue object\n" ; }
  template<typename T>
  template<typename U>
   void A<T>::f(U const& x) && { std::cout << "rvalue object\n" ; }

// template class A<int> ;
// template void A<int>::f<int>(int const&) & ;
// template void A<float>::f<int>(int const&) &&;


int main(){

  A<int>   a    ;
           a.f<int>(2); // lvalue
  A<float>().f<int>(1); // rvalue
}

代码运行,除非我尝试将其分解为单独编译 (*.hh、*.cc、*.ie 和 main)。 (注释掉的)声明将发布 一个编译器 ICE。

我看不出实例化语法有什么问题。有人可以 帮我解决这个问题...

【问题讨论】:

  • 您遇到的确切错误是什么?这是什么语言,C?
  • C++,在 gcc-4.9.3 和 gcc-6.1.0 中存在同样的问题(顺便说一句,它的编译安装时间是 4.9.3 的四倍)。你得到的错误很奇怪,没有必要复制。

标签: c++ templates ref-qualifier


【解决方案1】:

代码运行,除非我尝试将其分解为单独编译(*.hh、*.cc、*.ie 和 main)。

使用模板,您无法将标头和实现分开。它必须集中在一个地方。你必须做这样的事情(记住,我没有测试过):

A.hpp:

#include <iostream>
using std::cout;


template<typename T>
class A{
  public:
  template<typename U>
  void f(U const&)  & ;
  template<typename U>
  void f(U const&) && ;
};

  // Consider just throwing this in the class definition itself
  template<typename T>
  template<typename U>
   void A<T>::f(U const& x)  & { std::cout << "lvalue object\n" ; }
  template<typename T>
  template<typename U>
   void A<T>::f(U const& x) && { std::cout << "rvalue object\n" ; }

main.cpp

#include "A.hpp"

int main(){
  A<int>   a;
           a.f<int>(2); // lvalue
  A<float>().f<int>(1); // rvalue
}

【讨论】:

  • 我知道它是一体式的。它在单独编译中失败。我像这样单独编译模板:*.hh、*.cc(包含模板实例化,我称之为 *.ie)。然后所有编译,最后实例化并进入库。当然,实例化我关心实例化多少/多少。那些进入图书馆(不多)。
  • 您必须准确地分解它们是如何分离它们的(向我们展示每个文件中的内容)。如果你将模板的实现与模板类定义分开,那是行不通的。
【解决方案2】:
// ---------------- *.hh ------------

#include <iostream>
using std::cout;


#include <iostream>

template<typename T>
class A{
  public:
  void f()  & ;
  void f() && ;
  void g()  ;
  void g(int)  ;
};


// ---------- *.cc -- you compile this (no linking) just lib code ------
#include "e.hh"

  template<typename T>
   void A<T>::f()  & { std::cout << "lvalue object\n" ; }
  template<typename T>
   void A<T>::f() && { std::cout << "rvalue object\n" ; }

  template<typename T>
   void A<T>::g()   { std::cout << "lvalue object\n" ; }
  template<typename T>
   void A<T>::g(int x)  { std::cout << "rvalue object\n" ; }

extern template class A<int> ;
//extern template class A<float> ;
//template void  A<int>::f(float const&)  & ;
//template void  A<int>::f<int>() && ;

template  void A<int>::f() &;
//template void  A<float>::f() && ;


template  void A<int>::g() ;      // see ! ... these work !
template  void A<int>::g(int) ;   // ... but not the ref-qual ones

// ---------------------- *.cc (main) --------------
// here you compile + link the previous one
#include <iostream>
#include "e.hh"
using std::cout;


int main(){

  A<int>   a    ;
           a.f(); // lvalue
//  A<float>().f(); // rvalue
           a.g(); // lvalue
           a.g(3); // lvalue
}

【讨论】:

  • note - clang 3.8/C++11, 14, 17/ 工作... gcc 没有 - bugzilla 似乎反应也很慢! ...我会切换到 Clang,但 LLVM 很慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
  • 2011-04-11
  • 1970-01-01
  • 2021-03-14
  • 2016-09-23
  • 1970-01-01
相关资源
最近更新 更多