c++ - 迭代可变参数模板类的基类

标签 c++ templates c++11 variadic-templates

如何遍历可变参数模板类的所有基类并为每个基类调用一个函数。

这是一个最小的例子:

struct A { void foo() { std::cout << "A" << std::endl; } };
struct B { void foo() { std::cout << "B" << std::endl; } };
struct C { void foo() { std::cout << "C" << std::endl; } };

template<typename... U>
struct X : public U...
{
    void foo() {
        static_cast<U*>(this)->foo()...; // ??? should call `foo` for all `U`
    }
};

int main() {
    X<A,B,C> x;
    x.foo();
}

最佳答案

你通常不能没有 C++17 的折叠表达式。那里的省略号无效,星号后面的省略号将创建一个指针模板参数列表。对于要重复的适当模式,省略号必须位于语句的末尾,这在这里不起作用。我找到了 this article成为扩展包的好资源。

相反,一个不需要构建任何递归事物的技巧:

int arr[] = {(static_cast<U*>(this)->foo(), 0)...};

这会调用每个函数,然后将结果与逗号运算符一起使用以生成所需的 int。不幸的是,这可能会导致未使用的变量警告。解决此问题的一种最小方法是使用 std::array(或某些可以使用初始化列表初始化的类)并将创建其中一个未命名的结果转换为 void(转换为 void 是一种通常用于防止警告的常见技术)。

关于c++ - 迭代可变参数模板类的基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23462895/

相关文章:

c++ - std::function 表达式不会产生接受 1 个参数的函数

c++ - Debian 上的音频采样

c++ - 可以在模板化的 typedef 上使用模板特化吗?

c++ - 带有 g++ (Ubuntu) 的 virtual 关键字的奇怪 (?) 行为

C++ 可链接属性

c++ - 在 C++ 中增量构建编译时间列表

c++ - 从函数模板参数中推导复杂类型

cuda 5.0支持的c++版本

c++ - 为什么 "bool c = nullptr ;"编译(C++ 11)?

c++ - 如何将 IntPtr 类型的参数从 C# 项目传递到我的 COM DLL 项目