繁体   English   中英

变异模板构造函数和复制构造函数

[英]Variadic template constructor and copy constructor

我不明白为什么编译器选择我的Production类的复制构造函数而没有其他候选函数。 我做了一个最小的例子来演示错误:

#include <string>
#include <typeindex>
#include <iostream>

struct DummyProduction {
};

struct Dep {
};

struct Pro {
};

class ModuleBase {
};

template<typename Production = DummyProduction>
class Provider {
public:
  template<typename... Dependencies>
  Provider(ModuleBase& module, Dependencies... args)
  {
    std::cout << "Provider called!" << std::endl;
  }
  Provider(const Provider&) = delete;
};

class TargetController : public ModuleBase,
  public Provider<Pro>,
  public Provider<>
{
public:
  TargetController();
private:
  Dep p;
};

TargetController::TargetController() :
  ModuleBase(),
  Provider<Pro>(*this, &p),
  Provider<>(*this),
  p()
{
}

int main()
{
  TargetController x;
  return 0;
}

我用gcc和clang试了一下。 以下是非工作示例的链接link

对于Provider<Pro>(*this, p) ,调用正确的构造函数。 但是对于第二个示例Provider<>(*this) ,编译器会尝试调用copy-constructor。

根据我从重载解析页面的理解,所有与表达式匹配的函数都应该进入候选函数集。 但是,如果没有依赖关系,可变参数构造函数不在Provider的集合内,或者编译器选择了复制构造函数,尽管它已被删除。

有没有办法避免这种行为?

deleted函数/方法的事实不会将其从重载列表中删除。 复制构造函数优先于模板方法(因为它不是完全匹配)。

作为解决方法,您可以将其转换为预期类型:

TargetController::TargetController() :
  ModuleBase(),
  Provider<Pro>(*this, p),
  Provider<>(static_cast<ModuleBase&>(*this))
{
}

演示

模板化构造函数永远不会复制构造函数。 当你调用base的构造函数并向它传递一个对base(或派生)的引用时,应该调用复制构造函数。 该模板不是该上下文中的选项。

Provider<>(*this)

是这样的背景。

值得注意的是,我相信VS仍然会出错。 在那个编译器中你必须转换为base&或它将调用模板。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM