如何解压空的可变参数模板列表
How to unpack empty variadic template list
我阅读了 个问题并认为它很有趣,所以我开始尝试一些代码以查看是否可以让它工作,但我 运行 遇到了一个问题。
我的方法是使用函数式编程熟悉的头尾成语。但是,我找不到处理空可变参数模板列表的方法,这将是基本情况。
这是我的代码:
#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' is not a class template
,所以我尝试转发声明它,但出现了这个错误:
error: wrong number of template arguments (0, should be at least 2)
我该如何修正我的方法?
你有两个问题。
首先,在前向声明中,您说您的模板总是 接受至少两个参数(T1
和T2
)。如果你不想让你的结构有任何参数,你需要 forward-declare 它只有可变参数:
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;
}
这会打印 false
和 true
,这对我来说似乎是正确的结果。
你的专业是错误的。 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
}
我阅读了
我的方法是使用函数式编程熟悉的头尾成语。但是,我找不到处理空可变参数模板列表的方法,这将是基本情况。
这是我的代码:
#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' is not a class template
,所以我尝试转发声明它,但出现了这个错误:
error: wrong number of template arguments (0, should be at least 2)
我该如何修正我的方法?
你有两个问题。
首先,在前向声明中,您说您的模板总是 接受至少两个参数(T1
和T2
)。如果你不想让你的结构有任何参数,你需要 forward-declare 它只有可变参数:
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;
}
这会打印 false
和 true
,这对我来说似乎是正确的结果。
你的专业是错误的。 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
}