C++ std::get中的元组重复类型T<;T>;(元组)-编译时断言失败

C++ std::get中的元组重复类型T<;T>;(元组)-编译时断言失败,c++,windows,c++14,variadic-templates,stdtuple,C++,Windows,C++14,Variadic Templates,Stdtuple,我将可变参数存储到std::tuple中的对象构造函数中,目前为止效果良好。但是,当使用存储的参数和std::get()调用对象函数时,我将遇到编译时的断言失败,我完全不理解。只有当所有参数的类型不同时才会发生这种情况 编译器错误消息为: msvc\14.16.27023\include\tuple(934):错误C2338:中的重复类型T 获取(元组) mcve如下: #include <tuple> #include <iostream> using namespa

我将可变参数存储到
std::tuple
中的对象构造函数中,目前为止效果良好。但是,当使用存储的参数和
std::get()
调用对象函数时,我将遇到编译时的断言失败,我完全不理解。只有当所有参数的类型不同时才会发生这种情况

编译器错误消息为:

msvc\14.16.27023\include\tuple(934):错误C2338:中的重复类型T 获取(元组)

mcve如下:

#include <tuple>
#include <iostream>

using namespace std;

template<class... Args>
struct store_in_tuple {

    tuple<Args...> m_tuple_args;

    store_in_tuple(Args... args) : m_tuple_args{ args... } {}

    void func() {
        func_tuple(std::get<Args>(m_tuple_args)...);
    }

    void func_tuple(Args... args) {}
};

int main(int argc, char** argv) {

    store_in_tuple<int, float, double, int> sit1(1, 2.0f, 3.0, 4);
    sit1.func(); // <- not ok

    store_in_tuple<int, float, double, size_t> sit2(1, 2.0f, 3.0, 4);
    sit2.func(); // <- ok

    return 0;
}
#包括
#包括
使用名称空间std;
模板
结构存储在元组中{
元组m_tuple_args;
存储在元组(Args…Args)中:m_tuple_Args{Args…}{
void func(){
func_tuple(std::get(m_tuple_args)…);
}
void func_元组(Args…Args){}
};
int main(int argc,字符**argv){
存储在元组sit1中(1,2.0f,3.0,4);

sit1.func();//该示例可以简化为以下内容:

auto t = std::make_tuple(1, 's', 2);
std::get<int>(t);
扩展后,如果
Args…
至少包含一个重复类型,则
std::get
将不起作用,因为它根本不知道要获取哪个类型。

用于将元组的所有元素传递给函数

std::apply([&](auto... x){ func_tuple(x...); }, m_tuple_args);
你坚持使用C++14?
没问题,cppreference.com展示了一个简短而简单的生产质量示例实现

或者,您可以直接使用获取唯一索引,而不是重复的类型

为什么会发生这种情况[?]

Args…
类型都不同时,一切都很顺利

当类型发生冲突时会出现错误

这是因为
std::get(tuple_val)
,其中
T
是一种类型,“除非tuple正好有一个该类型的元素,否则无法编译”(如您所读)。这对我来说似乎是合理的

所以一切顺利

store_in_tuple<int, float, double, size_t> 

如果你能使用C++17,你可以使用
std::apply()
(我想)在引擎盖下使用
std::index_序列。

谢谢,这为我澄清了std::index_序列的用法。我不想使用帮助函数,所以我会使用C++17的apply或…你输入了std::get()的数字版本,这意味着什么?我可以用它在C++14中打开一个参数包吗?谢谢!编辑:只需阅读文档,无需回答:@PinkTurtle-对于“std::get()
”的数字版本,我指的是作为模板参数接收一个
std::size\u t
,而不是一个类型的
std::get()
。(案例从(1)到(4)在中。我不完全理解您的以下问题,但您可以看到在C++11(及更新版本)中解包参数包的方法是通常的:您可以在
func\u helper()
中看到它。这里的问题是生成索引的参数包;您需要
std::make\u index\u sequence
std::index\u sequence\u for
(这几乎是一样的)。(continue)@PinkTurtle-(continue)不幸的是
std::index_sequence
只能从C++14开始使用,我看不到不定义辅助函数就生成索引序列的方法。从C++17开始,可以使用
std::apply()负责生成索引序列并使用
std::get()的
,数字版。它对我来说很有效,使用了一个helper func和
index\u sequence\u for
。谢谢!我认为当对类实例方法使用
std::apply
时,必须在元组前面加上实际实例,以便它成为函数/callable的第一个参数,但我负担不起额外的副本;)
store_in_tuple<int, float, double, size_t> 
store_in_tuple<int, float, double, int>
template <std::size_t ... Is>
void func_helper (std::index_sequence<Is...> const)
 { func_tuple(std::get<Is>(m_tuple_args)...); }

void func ()
 { func_helper(std::index_sequence_for<Args...>{}); }