C++ 如何解包空变量模板列表

C++ 如何解包空变量模板列表,c++,c++11,metaprogramming,c++14,variadic-templates,C++,C++11,Metaprogramming,C++14,Variadic Templates,我读了这个问题,觉得它很有趣,所以我开始玩一些代码,看看是否可以让它工作,但我遇到了一个问题 我的方法是使用函数式编程所熟悉的头尾习惯用法。然而,我找不到一种方法来处理一个空的可变模板列表,这将是基本情况 这是我的密码: #include <iostream> #include <type_traits> class A {}; class B : public A {}; class C {}; class D : public C {}; /* // Forwa

我读了这个问题,觉得它很有趣,所以我开始玩一些代码,看看是否可以让它工作,但我遇到了一个问题

我的方法是使用函数式编程所熟悉的头尾习惯用法。然而,我找不到一种方法来处理一个空的可变模板列表,这将是基本情况

这是我的密码:

#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
}
#包括
#包括
A类{};
B类:公共A{};
C类{};
D类:公共C{};
/*
//远期申报
模板
结构是可转换的;
*/
//没有Args
模板
结构是可转换的{
静态常量布尔值=真;
};
//检查前两个元素是否可转换,然后在其余元素上递归
模板
结构是可转换的{
静态常量bool value=std::is_convertable::value&&are_convertable::value;
};
int main(){
你有两个问题

首先,使用前向声明,您可以说模板始终接受至少两个参数(
T1
T2
)。如果希望不允许结构使用任何参数,则只需使用可变参数对其进行前向声明:

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;
}
A类{};
B类:公共A{};
C类{};
D类:公共C{};
模板
结构是可转换的;
//没有Args
模板
结构是可转换的{
静态常量布尔值=真;
};
//检查前两个元素是否可转换,然后在其余元素上递归
模板
结构是可转换的{
静态常量bool value=std::is_convertable::value&&are_convertable::value;
};
int main(){

std::cout您的专门化是错误的。
T1
T2
消失。部分专门化
T1
T2
,这意味着
Args…
没有其他参数。代码如下:

#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 <typename T1, typename T2>
struct are_convertible<T1, T2> {
    static const bool value = std::is_convertible<T1, T2>::value;
};

// 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
}
#包括
#包括
A类{};
B类:公共A{};
C类{};
D类:公共C{};
//远期申报
模板
结构是可转换的;
//没有Args
模板
结构是可转换的{
静态常量布尔值=标准::可转换::值;
};
//检查前两个元素是否可转换,然后在其余元素上递归
模板
结构是可转换的{

static const bool value=std::is_convertable::value&&are_convertable

您是如何尝试向前声明它的?@Petr编辑了这个问题。您是否厌倦了在向前声明中只保留可变参数(即drop
T1
T2
)?嗯,您的专门化是错误的。T1和T2消失了。与您链接的问题不同,您的代码似乎假设调用者希望为随后的每对类型测试
是否可转换。这是有意的吗?提供的两种解决方案都是好的,但这一个特别解决了空变量(即,
)。