我正在尝试使用基于策略的设计来概括我的类,似乎 gcc 没有看到在基类中实现的纯虚函数的实现。下面是一个示例:
#include <iostream>
template <typename ReturnValue, template <typename> class... AccessPolicies>
struct testInterface : public AccessPolicies< ReturnValue >::interface...
{
};
template <typename DataClass, typename ReturnValue, template <typename> class... AccessPolicies>
struct testImplementation : public DataClass,
public testInterface< ReturnValue, AccessPolicies... >,
public AccessPolicies< ReturnValue >::template implementation< DataClass >...
{
};
template < typename ReturnValue >
struct GetByIndex;
template <>
struct GetByIndex< std::string >
{
class interface
{
public:
virtual std::string operator[](size_t ) = 0;
protected:
virtual ~interface() = default;
};
template <class DataClass>
class implementation
{
public:
virtual std::string operator[](size_t )
{
return "test by index";
}
protected:
virtual ~implementation() = default;
};
};
template < typename ReturnValue >
struct GetByName;
template <>
struct GetByName< std::string >
{
class interface
{
public:
virtual std::string operator[](std::string ) = 0;
protected:
virtual ~interface() = default;
};
template <class DataClass>
class implementation
{
public:
virtual std::string operator[](std::string )
{
return "test by string";
}
protected:
virtual ~implementation() = default;
};
};
struct data
{
};
int main()
{
testImplementation< data, std::string, GetByIndex, GetByName> test;
testInterface< std::string, GetByIndex, GetByName >& Test = test;
std::cout << Test[5] << std::endl;
return 0;
}
我收到的错误是:
..nienazwanymain.cpp: In function 'int main()':
..nienazwanymain.cpp:78:67: error: cannot declare variable 'test' to be of abstract type 'testImplementation<data, std::basic_string<char>, GetByIndex, GetByName>'
testImplementation< data, std::string, GetByIndex, GetByName> test;
^
..nienazwanymain.cpp:10:8: note: because the following virtual functions are pure within 'testImplementation<data, std::basic_string<char>, GetByIndex, GetByName>':
struct testImplementation : public DataClass,
^
..nienazwanymain.cpp:53:29: note: virtual std::string GetByName<std::basic_string<char> >::interface::operator[](std::string)
virtual std::string operator[](std::string ) = 0;
^
..nienazwanymain.cpp:26:29: note: virtual std::string GetByIndex<std::basic_string<char> >::interface::operator[](size_t)
virtual std::string operator[](size_t ) = 0;
^
..nienazwanymain.cpp:81:24: error: request for member 'operator[]' is ambiguous
std::cout << Test[5] << std::endl;
^
..nienazwanymain.cpp:53:29: note: candidates are: virtual std::string GetByName<std::basic_string<char> >::interface::operator[](std::string)
virtual std::string operator[](std::string ) = 0;
^
..nienazwanymain.cpp:26:29: note: virtual std::string GetByIndex<std::basic_string<char> >::interface::operator[](size_t)
virtual std::string operator[](size_t ) = 0;
有两个问题我不太明白:
- 编译器似乎不认为
AccessPolicy< ReturnType >::implementation< DataClass >...
是AccessPolicy< ReturnType >::interface...
的实现,即使函数签名完全相同。 - 编译器无法解析我调用的运算符 [],即使它们都有不同的参数,我清楚地调用了size_t运算符(数字不能隐式转换为字符串)。
任何想法为什么会这样?
我的猜测是,即使我直接从"接口"和"实现"继承,成员函数也会以某种方式在不同的命名空间中结束。如果这是正确的,我该如何解决这个问题?
编辑:根据要求添加了上述剥离模板的示例
#include <iostream>
class GetByIndexInterface
{
public:
virtual std::string operator[](size_t ) = 0;
protected:
virtual ~GetByIndexInterface() = default;
};
class GetByIndexImplementation
{
public:
virtual std::string operator[](size_t )
{
return "test by index";
}
protected:
virtual ~GetByIndexImplementation() = default;
};
class GetByNameInterface
{
public:
virtual std::string operator[](std::string ) = 0;
protected:
virtual ~GetByNameInterface() = default;
};
class GetByNameImplementation
{
public:
virtual std::string operator[](std::string )
{
return "test by string";
}
protected:
virtual ~GetByNameImplementation() = default;
};
struct data
{
};
struct testInterface : public GetByIndexInterface,
public GetByNameInterface
{
};
struct testImplementation : public data,
public testInterface,
public GetByIndexImplementation,
public GetByNameImplementation
{
};
int main()
{
testImplementation test;
testInterface& Test = test;
std::cout << Test[5] << std::endl;
return 0;
}
你struct testImplementation
继承自struct testInterface
本身,继承自定义virtual std::string operator[](std::string ) = 0;
struct GetByNameInterface
testInterface
和testImplementation
都没有为这个虚拟定义覆盖,所以testImplementation
是一个抽象的结构。
事实上,你从另一个与前一个类没有关系但定义了相同的operator
继承,这对你没有帮助。您必须在具体实现和抽象接口之间的层次结构中实现方法,而不是在侧类上实现。
为了做到这一点,你implementation
类必须从你的interface
类继承,这样实现将被接受,但正如之前所说,从具有抽象函数实现的不相关类继承,并不意味着实现的函数应该被视为抽象函数的实现