C++ 有没有办法将std::get(std::tuple)与非常量int一起用作模板参数?

C++ 有没有办法将std::get(std::tuple)与非常量int一起用作模板参数?,c++,for-loop,templates,tuples,constexpr,C++,For Loop,Templates,Tuples,Constexpr,我试图找出如何循环遍历std::tuple的成员,但似乎我只能在std::get模板参数中使用constepr ints或const ints。我环顾四周,看到了一些使用递归函数或结构的解决方案或想法,但我并不真正理解它们。我非常感谢您的帮助(我的代码如下) #包括 #包括 int main(){ std::tuple-tuple(3,4); 对于(int i=0;idecltype(func(std::get(tuple))) { 开关(索引){ 案例0:返回func(std::get(tup

我试图找出如何循环遍历
std::tuple
的成员,但似乎我只能在
std::get
模板参数中使用
constepr ints
const ints
。我环顾四周,看到了一些使用递归函数或结构的解决方案或想法,但我并不真正理解它们。我非常感谢您的帮助(我的代码如下)

#包括
#包括
int main(){
std::tuple-tuple(3,4);
对于(int i=0;i<2;i++)

std::cout问题在于,如果编译器不知道要访问哪个索引,它(通常)无法知道从元组返回哪种类型。因此诀窍是不返回任何内容。通常,使用使用使用switch语句的帮助函数来决定要使用哪种类型,并将函数传递给该类型

我手边没有编译器,但它看起来有点像这样:

 template<class Func, class... Args>
 auto apply_indexed(Func&& func, std::tuple<Args...>& tuple, int index) 
 -> decltype(func(std::get<0>(tuple)))
 {
     switch(index) {
     case 0: return func(std::get<0>(tuple);
     case 1: return func(std::get<1>(tuple);
     }
     throw std::invalid_argument("illegal index to invoke_tuple " + std::to_string(index));
 }
 
int main() {
    std::tuple<int, int> tuple(3, 4);
    
    for (int i = 0; i < 2; i++)
        apply_indexed([](auto& element){
            std::cout << element << std::endl;
        }, tuple, index);
}
模板
自动应用索引(Func&&Func,std::tuple&tuple,int-index)
->decltype(func(std::get(tuple)))
{
开关(索引){
案例0:返回func(std::get(tuple);
案例1:返回func(std::get(tuple);
}
抛出std::invalid_参数(“调用_元组的非法索引”+std::to_字符串(索引));
}
int main(){
std::tuple-tuple(3,4);
对于(int i=0;i<2;i++)
应用索引([](自动和元素){

std::cout问题在于,如果编译器不知道要访问哪个索引,它(通常)无法知道从元组返回哪种类型。因此诀窍是不返回任何内容。通常,使用使用使用switch语句的帮助函数来决定要使用哪种类型,并将函数传递给该类型

我手边没有编译器,但它看起来有点像这样:

 template<class Func, class... Args>
 auto apply_indexed(Func&& func, std::tuple<Args...>& tuple, int index) 
 -> decltype(func(std::get<0>(tuple)))
 {
     switch(index) {
     case 0: return func(std::get<0>(tuple);
     case 1: return func(std::get<1>(tuple);
     }
     throw std::invalid_argument("illegal index to invoke_tuple " + std::to_string(index));
 }
 
int main() {
    std::tuple<int, int> tuple(3, 4);
    
    for (int i = 0; i < 2; i++)
        apply_indexed([](auto& element){
            std::cout << element << std::endl;
        }, tuple, index);
}
模板
自动应用索引(Func&&Func,std::tuple&tuple,int-index)
->decltype(func(std::get(tuple)))
{
开关(索引){
案例0:返回func(std::get(tuple);
案例1:返回func(std::get(tuple);
}
抛出std::invalid_参数(“调用_元组的非法索引”+std::to_字符串(索引));
}
int main(){
std::tuple-tuple(3,4);
对于(int i=0;i<2;i++)
应用索引([](自动和元素){
标准::cout
有没有办法将std::get(std::tuple)与非常量int一起用作模板参数

不,没有。模板参数始终是编译时常量

此外,返回类型在编译时也是固定不变的,并且由于元组元素可以是不同的类型,编译器不知道返回什么类型,这将是一个问题

现在,即使您不能使用运行时参数
std::get
,也可以通过一些方法来迭代元素。来自标准库的
std::apply
将调用提供的以元组元素为参数的函数。您可以使用可变模板参数来接受任何元组,并使用折叠表达式展开参数离子

auto visitor = [](auto&&... args) {
    ((std::cout << args << '\n'), ...);
};
std::apply(visitor, tuple);
auto visitor=[](自动和…参数){
((std::cout)
有没有办法将std::get(std::tuple)与非常量int一起用作模板参数

不,没有。模板参数始终是编译时常量

此外,返回类型在编译时也是固定不变的,并且由于元组元素可以是不同的类型,编译器不知道返回什么类型,这将是一个问题

现在,即使您不能使用运行时参数
std::get
,也可以通过一些方法来迭代元素。来自标准库的
std::apply
将调用提供的以元组元素为参数的函数。您可以使用可变模板参数来接受任何元组,并使用折叠表达式展开参数离子

auto visitor = [](auto&&... args) {
    ((std::cout << args << '\n'), ...);
};
std::apply(visitor, tuple);
auto visitor=[](自动和…参数){

((std::cout您遇到的问题是
std::get
需要一个编译时值,而变量
i
仅在运行时已知。您可以执行以下操作:

std::tuple<int, int> tuple(3, 4);
std::cout << std::get<0>(tuple) << std::endl;
std::cout << std::get<1>(tuple) << std::endl;
这是一个例子


在C++17中,您可以使用折叠表达式,而无需为包扩展创建临时数组:

((std::cout << std::get<Is>(t) << std::endl), ...);

((std::cout您遇到的问题是
std::get
需要一个编译时值,而变量
i
仅在运行时已知。您可以执行以下操作:

std::tuple<int, int> tuple(3, 4);
std::cout << std::get<0>(tuple) << std::endl;
std::cout << std::get<1>(tuple) << std::endl;
这是一个例子


在C++17中,您可以使用折叠表达式,而无需为包扩展创建临时数组:

((std::cout << std::get<Is>(t) << std::endl), ...);

C++ C++((C++)11:C++ C++ 14是不同的。我假设C++ 14是好的。@ MOOIGIN NED是的,C++ 14是好的。模板参数总是“代码> CONTXPRP</代码>。C++没有任何其他的工作方式。所以对具体问题的简短回答是“不,没有办法”。然而,“如何迭代元组”。这是一个完全不同的问题。如果按照你的例子只有两个,我不会循环使用它们,我只会使用常量
0
1
独立打印它们。@Rahul:“那么,我如何迭代元组?”C++ C++ 11 C++ C++语言14的答案是不同的。我假设C++ 14是好的。@ MOOIGIN NED是的,C++ 14是好的。模板参数总是“代码> CONTXPRP</代码>。C++没有任何其他的工作。所以对具体问题的简短回答是“不,没有办法”。“如何迭代元组”是一个完全不同的问题。如果按照您的示例只有两个元组,我不会循环它们,我只会使用常量
0
1
独立打印它们。@Rahul:“那么我如何迭代元组?”这是一个完全不同的问题。