假设我有std::tuple
种类型。我不知道它包含多少或哪些类型,但我知道每个元素都有一个构造函数只接受一个参数。
为了这个问题,让我们说参数是整数5
,但是直到运行时才知道该值。
我如何构建这样的元组?
这是我到目前为止的尝试,它尝试使用编译时常量构造元组(不我想要的,但它是一个起点):
#include <tuple>
struct Fixture
{
// I don't know the value until runtime, so this is a poor
// example anyway.
template <typename T>
struct Unpack
{
static const int value = 5;
};
template <typename... T>
struct Y
{
Y()
:
// this needs to be a runtime value
tup(Unpack<T>::value...)
{
}
std::tuple<T...> tup;
};
Y<int, double, unsigned /*, some other classes */> y;
};
除了丑陋(不应该Unpack
类)并且只使用编译时已知的常量值时,这也会导致链接器错误:
架构x86_64的未定义符号:
&#34; Fixture :: Unpack :: value&#34;,引自: testTest.cpp.o中的Fixture :: Y :: Y()ld:找不到架构x86_64 clang的符号:错误:链接器命令失败 退出代码1(使用-v查看调用)
标准库或Boost中是否有一些元编程魔法可以使这项工作,最好是更简洁的语法?我觉得std::integer_sequence
的某些内容可能对我有帮助,但我无法弄清楚如何!
答案 0 :(得分:1)
诀窍是构造一个引用可变参数包的表达式,但其值是您的参数。在扩展时,它将成为您的参数的重复。逗号运算符做得非常好:
template <typename... T>
struct Y
{
Y(int value)
: tup((void(sizeof(T)), value)...)
{ }
std::tuple<T...> tup;
};
转换为void
是为了明确地丢弃逗号左侧的值。 sizeof(T)
可以替换为引用T
的任何内容。
答案 1 :(得分:0)
删除值的const,你可以使用这个
template<typename T>
T Fixture::Unpack<T>::value{};
定义每个可能的&#34;解压缩类型&#34;。
然后你可以在运行时使用类似的东西来更新值:
int main() {
std::cin >> Fixture::Unpack<int>::value >> Fixture::Unpack<double>::value;
Fixture f;
std::cout << std::get<0>(f.y.tup) << " " << std::get<1>(f.y.tup);
}