((c ++)可变参数模板,可用于多个遗产声明-“…使用3个模板参数声明...”

问题描述 投票:0回答:2

我正在尝试为自己的AVR编程实现自己的std::is_base_of(avr-gcc尚不支持<type_traits>。我从the cppreference page上的可能的实现中汲取了灵感,它对 []]类型检查,但是,我要实现的是对一个基类的multiple类型的继承性进行静态执行的有效性检查。

为简单起见,我正在使用std::is_base_of用于下面的实际检查

,但是我的实际解决方案与上面链接的cppreference页面中的内容很接近。

我将使用它进行标签分派,更具体地说是允许以任何顺序使用选项标签。


选项标签

struct tOption {};
struct tThis : public tOption {};
struct tThat : public tOption {};
struct tElse {}; // Wrongly defined option tag!

单个传统验证器结构

template<typename TBase, typename TCandidate>
struct isBaseOf {
    isBaseOf() = delete;
    static const bool value = std::is_base_of<TBase, TCandidate>::value;
};

static_assert(isBaseOf<tOption, tThat>::value, "Invalid option tag!"); // OK!
static_assert(isBaseOf<tOption, tElse>::value, "Invalid option tag!"); // ERROR! Invalid option tag!

尝试多次检查

(上述isBaseOf声明的补充)
template<typename TBase, typename TCandidate, typename... TRest>
struct isBaseOf {
    isBaseOf() = delete;
    static const bool value = isBaseOf<TBase, TRest...>::value && 
                              std::is_base_of<TBase, TCandidate>::value;
};

这不起作用。从我所看到的,我不能使用不同数量的类型来重新声明模板。但是,在最后一个模板构造中,我至少需要两种类型。我尝试使用TBase作为唯一参数,并将值设置为true,但是仍然存在相同的问题:错误:使用3个模板参数重新声明


用法

如上所述,这仅限于一次检查。由于我的班级(此处未显示)对任意数量的选项标签都使用可变参数模板(并且avr-gcc不支持constexpr函数中带有for循环的完整c ++ 14),因此我希望能够使用参数解包并仍然检查所有选项标签是否都继承了我的基本标签(tOption)。

template<typename... TOptions>
class tMyClass {
    static_assert(isBaseOf<tOption, TOptions...>::value, "Invalid option tag(s)!"); // <--- THIS
    // ...
};

使用功能-丑陋和不需要的

我让它使用一个函数而不是另一个结构来工作,但是我认为这很令人困惑。我宁愿有一种方法来解决整个递归(静态)堆栈的问题。另外,这迫使我构造每个标签,这不是非常整齐的IMO。

template<typename TBase, typename TCandidate>
constexpr bool isBaseOf2(const TBase&, const TCandidate&) {
    return std::is_base_of<TBase, TCandidate>::value;
}

template<typename TBase, typename TCandidate, typename... TRest>
constexpr bool isBaseOf2(const TBase& base, const TCandidate&, const TRest&... rest) {
    return isBaseOf2(base, rest...) && std::is_base_of<TBase, TCandidate>::value;
}

static_assert(isBaseOf2(tOption{}, tThis{}, tThat{}), "Invalid option tag(s)!"); // OK!
static_assert(isBaseOf2(tOption{}, tThis{}, tElse{}), "Invalid option tag(s)!"); // ERROR! Invalid option tag(s)!

是否有其他方法可以使用其他数量的参数重新定义结构模板

,例如上面的[[尝试多次检查
中的方法?我正在尝试为我的AVR编程实现自己的std :: is_base_of(avr-gcc尚不支持

。我从cppreference页面上获得了可能的实现灵感,它...

c++ variadic-templates static-methods constexpr tag-dispatching
2个回答
0
投票
在c ++ 17中,您可以在fold-expression运算符上使用&&来实现此目的

template<typename Base, typename ...Candidates> struct is_base_of_multiple { static constexpr bool value = (std::is_base_of_v<Base, Candidates> && ...); // change std::is_base_of_v to your own implementation };

如果不能使用c ++ 17,但是可以使用c ++ 11,这是仅使用可变参数模板的另一种方法

0
投票
问题与

template<typename TBase, typename TCandidate, typename... TRest> struct isBaseOf { isBaseOf() = delete; static const bool value = isBaseOf<TBase, TRest...>::value && std::is_base_of<TBase, TCandidate>::value; };

© www.soinside.com 2019 - 2024. All rights reserved.