C++ 操纵可变模板参数列表

C++ 操纵可变模板参数列表,c++,templates,variadic-templates,variadic-functions,C++,Templates,Variadic Templates,Variadic Functions,我想使用模板参数列表中的某些类型操作一些数据。 在我的例子中,我想检查一些元素是否是某种Iterable,如果有,那么我想对它们使用std::advance 这就是我的想法:(很明显,它不会编译,但会给你我想要实现的正确想法) #包括 #包括 模板 无效的 开始(_funcpfunc、常量迭代器begin、常量迭代器end、_Args&…Args) { 迭代器pt=开始; 迭代器ptNext=begin; 对于(无符号整数i=0;inThreads();i++) { std::advance(p

我想使用模板参数列表中的某些类型操作一些数据。 在我的例子中,我想检查一些元素是否是某种Iterable,如果有,那么我想对它们使用
std::advance

这就是我的想法:(很明显,它不会编译,但会给你我想要实现的正确想法)

#包括
#包括
模板
无效的
开始(_funcpfunc、常量迭代器begin、常量迭代器end、_Args&…Args)
{
迭代器pt=开始;
迭代器ptNext=begin;
对于(无符号整数i=0;inThreads();i++)
{
std::advance(ptNext,partialSize);
this->getThreads(i)=std::thread(pFunc、pt、ptNext、std::forward(args)…);
pt=ptNext;
[](…){}(typeid(args)=typeid(迭代器)?std::advance(args,partialSize):false);
}
}
我认为问题在于(也许?),参数列表在编译时被扩展,然后它会看到,我想在某些东西上使用
std::advance
,这甚至可能不是一种可移植的类型

在上面的代码中,
begin
end
是数据序列的迭代器,
partialSize
变量告诉我们,线程应该只处理序列的一部分

因此,目标是,如果通过参数列表传递任何其他Iterable类型,比如:
std::vector::iterator
std::list::iterator
或甚至是
double*
,那么我想
std::advance
它们


这个问题有什么解决办法吗?我可以实现这样的功能吗?

我已经实现了一个函数,它可以推进传递给它的所有迭代器。它只是忽略任何其他类型的参数

该代码需要C++17,但可以移植到标准的早期版本

#include <iterator>
#include <type_traits>

template <class T, class = void>
struct is_iterator : std::false_type {};

template <class T>
struct is_iterator<T, std::void_t<typename std::iterator_traits<T>::iterator_category>> : std::true_type {};

template <class Distance, class T>
void advance_if_iterable_impl(Distance n, T& t)
{
    if constexpr (is_iterator<T>::value)
        std::advance(t, n);
}

template <class Distance, class... Args>
void advance_if_iterable(Distance n, Args&... args)
{
    (advance_if_iterable_impl(n, args), ...);
}

#include <iostream>

int main()
{
    int i = 42;
    const char* str = "Hello World!\n";

    advance_if_iterable(2, i, str);

    // `int` isn't an iterator, it stays the same
    std::cout << i << '\n';
    // `const char*` is a random iterator, so it was advanced by two
    std::cout << str;

    return 0;
}
#包括
#包括
模板
结构是_迭代器:std::false_type{};
模板
struct是_迭代器:std::true_type{};
模板
无效前进(如果可行)(距离n,T&T)
{
if constexpr(是迭代器::值)
标准:前进(t,n);
}
模板
如果可用,则无效前进(距离n,Args和…Args)
{
(如果可执行,则前进…);
}
#包括
int main()
{
int i=42;
const char*str=“你好,世界!\n”;
可提前(2,i,str);
//'int'不是迭代器,它保持不变

std::难道你很难理解你想要实现什么。例如,如果i-th arg不是迭代器,会发生什么?是的,这是我的问题。然后什么都不应该发生。这就是我想做的。不知何故,找出它是否是迭代器,然后才对其使用
advance
。但我想我在我的问题中说明了这一点。在
void a中距离(距离n,Args和…Args)
可能有一个
&
符号丢失了,但除此之外,它就像一个符咒。这就是我一直在寻找的。我认为这是不可能的!非常感谢!@SkyZip,
如果可用的话,则advance\u应该对左值引用进行操作,因为推进右值引用是没有意义的。粗略地说,右值引用e是对临时对象或预期要移动的对象的引用。