c++ - 如何解压空的可变参数模板列表

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

我读了this问题并认为它很有趣,所以我开始尝试一些代码以查看是否可以让它工作,但我遇到了一个问题。

我的方法是使用函数式编程熟悉的头尾成语。但是,我找不到一种方法来处理空的可变参数模板列表,这将是基本情况。

这是我的代码:

#include <iostream>
#include <type_traits>

class A {};
class B : public A {};
class C {};
class D : public C {};

/*

// Forward declaration
template <typename T1, typename T2, typename... Args>
struct are_convertible;

*/

// There are no Args
template <>
struct are_convertible<> {
    static const bool value = true;
};

// Check if the first two elements are convertible then recurse on the rest
template <typename T1, typename T2, typename... Args>
struct are_convertible {
    static const bool value = std::is_convertible<T1, T2>::value && are_convertible<Args...>::value;
};

int main() {
    std::cout << std::boolalpha;
    std::cout << "Are convertible A->B and C->D: " << are_convertible<A, B, C, D>::value << std::endl; // Should be false
}

我目前收到一个错误,指出 'are_convertible' 不是类模板,所以我尝试转发声明它,但出现了这个错误:

error: wrong number of template arguments (0, should be at least 2)

我该如何修正我的方法?

最佳答案

你有两个问题。

首先,在前向声明中,您说您的模板始终 接受至少两个参数(T1T2)。如果你不想让你的结构有任何参数,你需要只用可变参数转发声明它:

template<typename... Args>
struct are_convertible;

其次,您的第二个定义不是偏特化,而是与先前的前向声明相矛盾的完整通用(新)模板定义。您需要的是部分特化:

template <typename T1, typename T2, typename... Args>
struct are_convertible<T1, T2, Args...> {
                    //^^^^^^^^^^^^^^^^^

在此之后,您的代码可以工作了:

class A {};
class B : public A {};
class C {};
class D : public C {};

template<typename... Args>
struct are_convertible;

// There are no Args
template <>
struct are_convertible<> {
    static const bool value = true;
};

// Check if the first two elements are convertible then recurse on the rest
template <typename T1, typename T2, typename... Args>
struct are_convertible<T1, T2, Args...> {
    static const bool value = std::is_convertible<T1, T2>::value && are_convertible<Args...>::value;
};

int main() {
    std::cout << std::boolalpha;
    std::cout << "Are convertible A->B and C->D: " << are_convertible<A, B, C, D>::value << std::endl;
    std::cout << "Are convertible B->A and D->C: " << are_convertible<B, A, D, C>::value << std::endl;
}

这会打印出 falsetrue,这对我来说似乎是正确的结果。

关于c++ - 如何解压空的可变参数模板列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34616567/

相关文章:

C++ 纯虚错误

c++ - 将输出同步到 std::cout

c++ - 寻找类似 fetch_add 的atomic<double>之类的东西

Ruby:在不同的上下文中执行单例方法

c++ - 使用 boost::spirit 解析 double 列表

c++ - 如何在 C++ 中读取和解析 CSV 文件?

c++ - 使用函数地址的模板类的唯一数字 ID

c++函数代码泛化使用模板

c++ - Arduino:将 String hex "#FFFFFF"转换为 3 int

c++ - 使用 GUIDFromString 要求包括 Shell32.dll : How do I do that