gpt4 book ai didi

templates - 当基类和派生类都具有可变参数继承链时,避免模糊的 SFINAE 访问

转载 作者:行者123 更新时间:2023-12-01 02:17:55 26 4
gpt4 key购买 nike

使用 SFINAE,可以访问可变参数类模板的各个元素。当基类从可变参数类模板继承,然后派生类再次从基类和可变参数类模板继承(使用不同的模板参数)时,就会出现我的问题。关于应该遵循哪个继承链存在歧义。有没有办法解决歧义?

例如:

// compile with flag: -std=c++11
#include <type_traits>

struct A { int x; };
struct B { int x; };
struct C { int x; };
struct D { int x; };

template <class ... Params> class Parameter { };

template <class Param, class ... Tail>
class Parameter<Param, Tail ...> : public Param, public Parameter<Tail ...>
{
public:
//! Get a parameter
template <class Param2>
typename std::enable_if<std::is_same<Param, Param2>::value, int>::type
getParam() const
{ return Param::x; }

//! Get a parameter. Delegate false template matches down the Tail... inheritance line (see SFINAE)
template <class Param2>
typename std::enable_if<! std::is_same<Param, Param2>::value, int>::type
getParam() const
{ return Parameter<Tail ...>::template getParam<Param2>(); }
};

class Base : public Parameter<A, B>
{ };

class Derived : public Base, public Parameter<C, D>
{ };

int main(int const argc, char const * argv[])
{
Base base;
int a = base.getParam<A>(); // ok
int b = base.getParam<B>(); // ok

Derived derived;
int c0 = derived.getParam<C>(); // error: request for member ‘getParam’ is ambiguous
int c1 = derived.Derived::getParam<C>(); // error: request for member ‘getParam’ is ambiguous
int c2 = derived.Parameter<C, D>::getParam<C>(); // ok but syntax overly complex, especially if many params

int a0 = derived.getParam<A>(); // error: request for member ‘getParam’ is ambiguous
int a1 = derived.Base::getParam<A>(); // ok, could be acceptable if also worked on Derived
int a2 = derived.Parameter<A, B>::getParam<A>(); // ok but syntax overly complex and confusing

return 0;
}

我意识到几个主要的设计更改可以解决这个问题:1)摆脱可变参数类模板,而是一次从每个参数派生一个 2)使参数成为成员变量。但我的问题是我是否可以保留可变参数 Parameter 类模板同时避免歧义。

最佳答案

我会删除 getParam不匹配以避免歧义如下:Demo

template <class ... Params> class Parameter;

template <class Param>
class Parameter<Param> : public Param
{
public:
//! Get a parameter
template <class Param2>
typename std::enable_if<std::is_same<Param, Param2>::value, int>::type
getParam() const
{ return Param::x; }
};

template <class Param, class ... Tail>
class Parameter<Param, Tail ...> : public Parameter<Param>, Parameter<Tail...>
{
public:
using Parameter<Param>::getParam;
using Parameter<Tail...>::getParam;
};

class Base : public Parameter<A, B> {};

class Derived : public Base, public Parameter<C, D>
{
public:
using Base::getParam;
using Parameter<C, D>::getParam;
};

关于templates - 当基类和派生类都具有可变参数继承链时,避免模糊的 SFINAE 访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23126883/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com