【问题标题】:Compilation Errors while defining vector of tuple in C++11 using GCC v4.8 on Ubuntu 14.04在 Ubuntu 14.04 上使用 GCC v4.8 在 C++11 中定义元组向量时出现编译错误
【发布时间】:2019-03-08 08:52:47
【问题描述】:

我正在尝试在 C++ 11 中定义一个元组向量,如下所示:

#include <iostream>
#include <string>
#include <vector>
#include <tuple>

typedef unsigned char uchar;
typedef std::tuple<uchar, std::string, uchar, float> fruitInfoTuple;
const std::vector<fruitInfoTuple> jointsInfo{
  { 0,  "mango",   100,   -6.01},
  {10,  "apple",   144,    6.25},
  {12,  "orange",  159,    2.59},
  {33,  "banana",  144,  -28.96},
  { 4,  "grapes",  128,    3.79},
};

我在启用 C++11 标志的情况下编译程序。但是,它显示复杂错误,如下所示:

ravi@lab:~/Desktop/a$ g++  -std=c++11 learn.cpp 
learn.cpp:14:1: error: converting to ‘std::tuple<unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float>’ from initializer list would use explicit constructor ‘constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...) [with _UElements = {int, const char (&)[6], int, double}; <template-parameter-2-2> = void; _Elements = {unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float}]’
 };
 ^
learn.cpp:14:1: error: converting to ‘std::tuple<unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float>’ from initializer list would use explicit constructor ‘constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...) [with _UElements = {int, const char (&)[6], int, double}; <template-parameter-2-2> = void; _Elements = {unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float}]’
learn.cpp:14:1: error: converting to ‘std::tuple<unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float>’ from initializer list would use explicit constructor ‘constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...) [with _UElements = {int, const char (&)[7], int, double}; <template-parameter-2-2> = void; _Elements = {unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float}]’
learn.cpp:14:1: error: converting to ‘std::tuple<unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float>’ from initializer list would use explicit constructor ‘constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...) [with _UElements = {int, const char (&)[7], int, double}; <template-parameter-2-2> = void; _Elements = {unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float}]’
learn.cpp:14:1: error: converting to ‘std::tuple<unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float>’ from initializer list would use explicit constructor ‘constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...) [with _UElements = {int, const char (&)[7], int, double}; <template-parameter-2-2> = void; _Elements = {unsigned char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char, float}]’

我猜 GCC 4.8 不支持元组功能。请问有什么解决办法吗?请注意,如果需要,我可以使用boost。我只是想要一种像上面那样定义元组的干净方式。

【问题讨论】:

  • intuchar 的转换似乎是问题所在。
  • 请注意,GCC 4.8 中的 C++11 支持不完整。
  • 与您的问题无关,但与您的代码有关:除非您在小型嵌入式系统中,否则很少需要使用较小的整数类型。去intunsigned int。如果出于某种原因您仍想使用较小的整数类型,请使用 standard 小整数类型,例如uint8_t.
  • @Jarod42:它适用于较新的 GCC。但是,我现在只能使用 GCC 4.8。您能否建议任何替代方法,例如使用 boost 等?
  • @RaviJoshi 你仍然可以使用std::make_tuple

标签: c++ c++11 tuples stdtuple


【解决方案1】:

你可以试试:

const std::vector<fruitInfoTuple> jointsInfo{
    fruitInfoTuple{ 0,  "mango",   100,   -6.01},
    fruitInfoTuple{10,  "apple",   144,    6.25},
    fruitInfoTuple{12,  "orange",  159,    2.59},
    fruitInfoTuple{33,  "banana",  144,  -28.96},
    fruitInfoTuple{ 4,  "grapes",  128,    3.79},
};

【讨论】:

  • 它可以工作,但有没有办法在每一行的语法中删除fruitInfoTuple?我希望语法更简洁.....
  • { uchar(0), std::string("mango"), uchar(100), -6.01f} 也应该完成这项工作(没有隐式转换 intuchardoublefloatconst char*std::string),不确定你喜欢它不过。
【解决方案2】:

在 C++11 中你应该使用std::make_tuple 来构造元组:

#include <iostream>
#include <string>
#include <vector>
#include <tuple>

typedef unsigned char uchar;
typedef std::tuple<uchar, std::string, uchar, float> fruitInfoTuple;
const std::vector<fruitInfoTuple> jointsInfo{
  std::make_tuple( 0,  "mango",   100,   -6.01),
  std::make_tuple(10,  "apple",   144,    6.25),
  std::make_tuple(12,  "orange",  159,    2.59),
  std::make_tuple(33,  "banana",  144,  -28.96),
  std::make_tuple( 4,  "grapes",  128,    3.79),
};
int main()
{
    for(int i = 0 ; i < jointsInfo.size(); ++i)
    {
        std::cout << std::get<1>(jointsInfo[i]) << std::endl;

    }
}

结果:

mango
apple
orange
banana
grapes

【讨论】:

  • 它可以工作,但有没有办法在语法中删除std::make_tuple?我希望语法更简洁.....
  • std::make_tuple 是一个标准的 C++11 函数。我看不出它不是“干净”的语法。唯一的另一种方法是显式调用构造函数(参见@Jarod42 的答案)。升级您的编译器以支持 C++14 和 C++17 可能会提供其他方法来执行此操作。
猜你喜欢
  • 2014-12-10
  • 2016-11-20
  • 2022-07-15
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
相关资源
最近更新 更多