Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 完美转发无法链接到显式模板实例化指令(EIDir;又称手动实例化)_C++_C++14_Variadic Templates_Perfect Forwarding_Explicit Instantiation - Fatal编程技术网

C++ 完美转发无法链接到显式模板实例化指令(EIDir;又称手动实例化)

C++ 完美转发无法链接到显式模板实例化指令(EIDir;又称手动实例化),c++,c++14,variadic-templates,perfect-forwarding,explicit-instantiation,C++,C++14,Variadic Templates,Perfect Forwarding,Explicit Instantiation,问题是,当构造函数定义隐藏在实现文件(*.cpp)中,但在main.cpp中显式实例化时,为什么链接器(g++,7.5版,Ubuntu 18.4版)无法完美转发模板类的构造函数 具体而言: fwd\u机器。水电站: #include <memory> #include <stdexcept> template<typename T> struct some_type { some_type(int, void*); // ld error: undefin

问题是,当构造函数定义隐藏在实现文件(*.cpp)中,但在main.cpp中显式实例化时,为什么链接器(g++,7.5版,Ubuntu 18.4版)无法完美转发模板类的构造函数

具体而言: fwd\u机器。水电站:

#include <memory>
#include <stdexcept>

template<typename T>
struct some_type
{
 some_type(int, void*); // ld error: undefined reference to `some_type<int>::some_type(int, void*)'

 // if no EIDir, i.e., defined in the header,
 // then it works fine:
 //
 //some_type(int, void*){}
 //
 // or:
 // if explicit specialization used (with pass-through version in the header)
 // then it also works fine:
 //
 // some_type(int, void*){
 //   throw std::runtime_error("Error: only specializations whould be called...");
 // }
 // okay
};

struct factory_t
{
 template<typename some_t, typename... Args>
 decltype(auto)
 operator()(Args&&... args)
 {
   return std::make_unique<some_t>(some_t(std::forward<Args>(args)...));
 }
};

template<typename FType, typename...Fargs>
constexpr
decltype(auto) launch(FType f, Fargs&&... args)
{
 return f.template operator()<some_type<int>>(std::forward<Fargs>(args)...);
}
#include "fwd_machine.hpp"

// if no EIDir, i.e., defined in the header,
// then it works fine...

// or:
// if explicit specialization used (with pass-through version in the header)
// then it also works fine:
//
//template<>
//some_type<int>::some_type(int, void*){} // okay

template<typename T>
some_type<T>::some_type(int, void*){} // ld error: undefined reference to `some_type<int>::some_type(int, void*)'
#include <iostream>
#include "fwd_machine.hpp"

// g++ -std=c++14 fwd_machine.cpp main_fwd_issues.cpp -o mfi.exe

// if no EIDir or specialization, then it works fine...
//
template class some_type<int>;

int main(void)
{
  int i{1};
  void* p{nullptr};

  auto uniq_p = launch(factory_t{}, i, p);

  std::cout<<"Finishing up...\n";
  return 0;
}
然后,我主要对整个类使用手动实例化: 主要问题。cpp:

#include <memory>
#include <stdexcept>

template<typename T>
struct some_type
{
 some_type(int, void*); // ld error: undefined reference to `some_type<int>::some_type(int, void*)'

 // if no EIDir, i.e., defined in the header,
 // then it works fine:
 //
 //some_type(int, void*){}
 //
 // or:
 // if explicit specialization used (with pass-through version in the header)
 // then it also works fine:
 //
 // some_type(int, void*){
 //   throw std::runtime_error("Error: only specializations whould be called...");
 // }
 // okay
};

struct factory_t
{
 template<typename some_t, typename... Args>
 decltype(auto)
 operator()(Args&&... args)
 {
   return std::make_unique<some_t>(some_t(std::forward<Args>(args)...));
 }
};

template<typename FType, typename...Fargs>
constexpr
decltype(auto) launch(FType f, Fargs&&... args)
{
 return f.template operator()<some_type<int>>(std::forward<Fargs>(args)...);
}
#include "fwd_machine.hpp"

// if no EIDir, i.e., defined in the header,
// then it works fine...

// or:
// if explicit specialization used (with pass-through version in the header)
// then it also works fine:
//
//template<>
//some_type<int>::some_type(int, void*){} // okay

template<typename T>
some_type<T>::some_type(int, void*){} // ld error: undefined reference to `some_type<int>::some_type(int, void*)'
#include <iostream>
#include "fwd_machine.hpp"

// g++ -std=c++14 fwd_machine.cpp main_fwd_issues.cpp -o mfi.exe

// if no EIDir or specialization, then it works fine...
//
template class some_type<int>;

int main(void)
{
  int i{1};
  void* p{nullptr};

  auto uniq_p = launch(factory_t{}, i, p);

  std::cout<<"Finishing up...\n";
  return 0;
}
#包括
#包括“fwd_machine.hpp”
//g++-std=c++14 fwd_machine.cpp main_fwd_issues.cpp-o mfi.exe
//如果没有EIDir或专门化,那么它可以正常工作。。。
//
模板类的一些类型;
内部主(空)
{
int i{1};
void*p{nullptr};
自动uniq_p=启动(工厂{},i,p);
标准::cout

完整的定义必须出现在类模板的显式实例化之前

当您尝试在
main.cpp
中实例化它时,程序中的情况并非如此

显式实例化某个类型的正确方法是添加

// in fwd_machine.hpp
extern template class some_type<int>;
//在fwd_machine.hpp中
外部模板类某些类型;
//在fwd_machine.cpp中(定义完成后):
模板类的一些类型;

谢谢。在
fwd_machine.cpp
中移动EIDir解决了这个问题。我真的不认为需要明确的实例化声明(
extern template…
),其目的是防止ATI(提高编译时间)…但是在这种情况下不需要它(我同意它不会造成伤害)@bluescorpion不客气!是的,我不认为有
extern…
声明会有什么好处,所以这就是我所做的(我很少使用显式实例化)。