对可变模板多继承函数调用的访问不稳定
Ambigious access on variadic template multi inheritence function call
因此,我正在研究如何解决"寻找设计模式以减少虚拟方法过载"中的问题
我的想法是使用可变模板来描述特定类可以接受哪些类型。这可能有一个小用例,但我喜欢玩模板。。。
以下是我(到目前为止)的想法:
struct Struct
{
virtual void doit() = 0;
};
struct StructA : Struct
{
void doit() { std::cout << "A" << std::endl; }
};
struct StructB : Struct
{
void doit() { std::cout << "B" << std::endl; }
};
struct StructC : Struct
{
void doit() { std::cout << "C" << std::endl; }
};
template <typename Type>
struct Accepter
{
void accept(const Type& t) { t.doit(); };
};
template <typename...Types>
struct MultiAccepter : Accepter<Types>... {};
当只将一个类型传递给MultiAccepter
时,一切都会按其应有的方式进行。只有当我传递了2个或多个模板参数类型时,问题才会出现。看起来编译器失去了在不同类型之间进行区分的能力。
int main()
{
StructA struct_a;
StructB struct_b;
Accepter<StructA> accept_a;
Accepter<StructB> accept_b;
MultiAccepter<StructA> accept_multi_a;
MultiAccepter<StructB> accept_multi_b;
MultiAccepter<StructA, StructB> accept_multi_ab;
accept_a.accept(struct_a); //OK
accept_b.accept(struct_b); //OK
accept_multi_a.accept(struct_a); //OK
accept_multi_b.accept(struct_b); //OK
accept_multi_ab.accept(struct_a); //NOK:
// error C2385: ambiguous access of 'accept'
// note : could be the 'accept' in base 'Accepter<StructA>'
// note : or could be the 'accept' in base 'Accepter<StructB>'
accept_multi_ab.accept(struct_b); //NOK:
// error C2385: ambiguous access of 'accept'
// note : could be the 'accept' in base 'Accepter<StructA>'
// note : or could be the 'accept' in base 'Accepter<StructB>'
// error C2664 : 'void Accepter<StructA>::accept(const Type &)' : cannot convert argument 1 from 'StructB' to 'const StructA &'
// with
// [
// Type = StructA
// ]
// note : Reason : cannot convert from 'StructB' to 'const StructA'
// note : No user - defined - conversion operator available that can perform this conversion, or the operator cannot be called
return 0;
}
尝试使用gcc 5.2
编译代码也不起作用:http://goo.gl/oVLHT8
我想这只是一个简单的问题,但我就是找不到解决办法。有人知道我做错了什么吗?
附言:这一侧的示例描述了类似的模式:http://natsys-lab.blogspot.de/2013/07/c-variadic-templates-and-multiple.html
更新:看起来基类Accepter<StructB>
定义了一个函数void accept(const StructA&)
。我仍然不明白为什么会这样。
我使用这里描述的模式来创建一个解决方案:https://stackoverflow.com/a/28349054/1149664
诀窍是一次继承一个基类Accepter<T0>
,然后将其余类型进一步推到继承链的上游。我还将方法设置为const以使其一致。你可以根据自己的需要随意调整。
#include "stdafx.h"
#include <functional>
#include <chrono>
#include <iostream>
struct Struct
{
virtual void doit() const = 0;
};
struct StructA : public Struct
{
void doit() const { std::cout << "A" << std::endl; }
};
struct StructB : public Struct
{
void doit() const { std::cout << "B" << std::endl; }
};
struct StructC : public Struct
{
void doit() const { std::cout << "C" << std::endl; }
};
template <typename Type>
struct Accepter
{
void accept(const Type& t) const { t.doit(); } ;
};
template <typename... Types>
struct MultiAccepter;
template <typename T0, typename...Types>
struct MultiAccepter<T0, Types...> : public Accepter<T0>, public MultiAccepter<Types...> {
using Accepter<T0>::accept;
using MultiAccepter<Types...>::accept;
};
template <typename T0>
struct MultiAccepter<T0> : public Accepter<T0> {
using Accepter<T0>::accept;
};
int main()
{
StructA struct_a;
StructB struct_b;
Accepter<StructA> accept_a;
Accepter<StructB> accept_b;
MultiAccepter<StructA> accept_multi_a;
MultiAccepter<StructB> accept_multi_b;
MultiAccepter<StructA, StructB> accept_multi_ab;
accept_a.accept(struct_a);
accept_b.accept(struct_b);
accept_multi_a.accept(struct_a);
accept_multi_b.accept(struct_b);
accept_multi_ab.accept(struct_a);
accept_multi_ab.accept(struct_b);
return 0;
}
相关文章:
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- C ++尝试访问映射中的元素会给我一个不匹配的函数调用错误
- 通过在基类中虚拟调用派生类中的函数来访问派生类中的函数
- 使用全局引用调用函数时访问冲突
- 函数调用不起作用,矢量访问数据
- 在析构函数调用后访问成员变量
- mfc应用程序结束后,CMainFrame的析构函数调用发生访问冲突
- 从 C++ 中的函数调用矩阵时访问矩阵中的元素
- 在析构函数调用时访问冲突读取位置0xfeeefe2
- 对可变模板多继承函数调用的访问不稳定
- 当右值对象作为函数调用的一部分访问其成员时被销毁
- 如何让一个函数参数接受不同的对象(但属于同一类),并访问传递给w/n函数调用的w/n对象的函数
- Shell程序中execvp函数调用返回无法访问错误
- Python-ctypes-如何调用函数和访问结构字段