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