Nag*_*gua 6 c++ constructor variadic-templates c++11 c++14
我不明白为什么编译器会选择我的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;
}
Run Code Online (Sandbox Code Playgroud)
我用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))
{
}
Run Code Online (Sandbox Code Playgroud)