我正在尝试创建从可变参数模板派生的类。这是代码:
struct Some { };
template < class Base, class T >
struct Feature
{
protected:
void DoStuff(T& t) { }
};
template < class T, class ... Ts >
struct MultiFeature
: public Feature< T, Ts >...
{
};
class TestFeature
: public MultiFeature< Some, std::int16_t, std::string >
{
public:
void TestDoStuff()
{
std::int16_t i;
DoStuff(i);
}
};
功能应该是一些基本类型(在这种情况下为整数和字符串)的简单包装,为从其派生的类提供一些功能。使用MultiFeature使得我不必从Feature< std::int16_t >
,Feature< std::string >
派生。
据我了解,在这种情况下应该没有歧义,因为有两个不同的DoStuff
函数,每个函数采用不同的参数类型,但是VS2017抱怨访问不明确。这是正确的行为吗?如果是这样,是否有解决此问题的简单方法?
编辑
似乎编译器就在这里,但是在此答案中,建议的解决方法是将using
(Ambiguous access to base class template member function)引入基类成员函数。是否可以对可变参数模板基类执行此操作?
答案 0 :(得分:0)
似乎编译器就在这里,但是在此答案中,建议的解决方法是通过使用将基类成员函数带入范围(对基类模板成员函数的歧义访问)。是否可以对可变参数模板基类执行此操作?
如果您可以使用C ++ 17,这很简单
template <typename T, typename ... Ts>
struct MultiFeature : public Feature<T, Ts>...
{
using Feature<T, Ts>::DoStuff...;
};
不幸的是,可变参数using
是在C ++ 17中引入的,因此,在C ++ 11和C ++ 14中,我能想到的最好的是MultiFeature
递归定义
// ground case: a fake DoStuff to abilitate following using
template <typename T, typename ... Ts>
struct MultiFeature
{ void DoStuff () { } };
// recursion case
template <typename T, typename T0, typename ... Ts>
struct MultiFeature<T, T0, Ts...>
: public Feature<T, T0>, public MultiFeature<T, Ts...>
{
using Feature<T, T0>::DoStuff;
using MultiFeature<T, Ts...>::DoStuff;
};
以下是完整的编译示例(两种情况)
struct Some { };
template <typename, typename T>
struct Feature
{
protected:
void DoStuff (T &) { }
};
#if 0
template <typename T, typename ... Ts>
struct MultiFeature : public Feature<T, Ts>...
{
using Feature<T, Ts>::DoStuff...;
};
#else
// ground case: a fake DoStuff to abilitate following using
template <typename T, typename ... Ts>
struct MultiFeature
{ void DoStuff () { } };
// recursion case
template <typename T, typename T0, typename ... Ts>
struct MultiFeature<T, T0, Ts...>
: public Feature<T, T0>, public MultiFeature<T, Ts...>
{
using Feature<T, T0>::DoStuff;
using MultiFeature<T, Ts...>::DoStuff;
};
#endif
struct TestFeature
: public MultiFeature<Some, short, int, long, long long>
{
void TestDoStuff ()
{ int a{}; DoStuff(a); }
};
int main ()
{
TestFeature tf;
}