2013-02-20 37 views
6

我想创建一个具有3个值的结构:一个字符串和两个整数。该字符串是强制性的,但是(或两者)都是可选的,如果未指定,则默认为-1。将从元组派生的对象放入C++中的向量中

但是,而不是使用一个结构,我想我会尝试一个std ::元组。为了将两个整数的可选的烦躁,我设置了“三重奏”类性病从继承::元组,如下:

#include <string> 
#include <tuple> 

class Trio : public std::tuple<std::string, int, int> 
{ 
    public: 

    explicit Trio(std::string const & name, int val1 = -1, int val2 = -1) 
    : 
     tuple(name, val1, val2) 
    { 
    } 
}; 

然后我去推一些三重奏对象来测试类三重奏到一个std ::向量:

#include <vector> 
int main(void) 
{ 
    std::vector<Trio> trios; 

    Trio trio("trio1", 1, 1); 
    trios.push_back(trio); 

    return 0; 
} 

它给了我在Visual Studio 2010中出现以下错误:

>c:\program files (x86)\microsoft visual studio 10.0\vc\include\tuple(127): 
    error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const 
    std::basic_string<_Elem,_Traits,_Ax> &)' : cannot convert parameter 1 
    from 'const Trio' to 'const std::basic_string<_Elem,_Traits,_Ax> &' 
with 
[ 
    _Elem=char, 
    _Traits=std::char_traits<char>, 
    _Ax=std::allocator<char> 
] 
Reason: cannot convert from 'const Trio' to 'const 
std::basic_string<_Elem,_Traits,_Ax>' 
with 
[ 
    _Elem=char, 
    _Traits=std::char_traits<char>, 
    _Ax=std::allocator<char> 
] 
No user-defined-conversion operator available that can perform 
this conversion, or the operator cannot be called 

有谁知道我在做什么错误吗?有没有什么明显的,我只是没有看到?我可能严重滥用std :: tuple的用法吗?

谢谢

亚伦

+0

在ideone上编译确定:http://ideone.com/9q0nxW – Bill 2013-02-20 19:10:41

+0

这为我编译与g ++ http://ideone.com/ZAIDUp – juanchopanza 2013-02-20 19:11:10

回答

8

这是一个错误的VC10。

VC10抱怨,因为你的班级没有似乎有复制构造函数。因此,为了复制Trio类型的值,它会尝试将它们转换为string,这是您提供的构造函数接受的(其他参数可以被赋予默认值)。这是你的错误抱怨:

不能从 '常量三重奏' 转换参数1 '常量的std :: basic_string的< _Elem,_Traits,_AX> &'

您可以验证这的确是什么是明确将一个拷贝构造函数怎么回事,看着错误消失:

Trio(Trio const& t) { *this = t; } 

现在VC10是满足,因为它看到一个拷贝构造函数,和代码编译罚款。

尽管如此,当用户没有明确提供拷贝构造函数时,编译器应该隐式地生成一个拷贝构造函数。每个段落的C++标准11 12.8/7:

如果类定义不明确声明拷贝构造函数,一个是隐式声明。如果类定义声明了移动构造函数或移动赋值操作符,则隐式声明的拷贝构造函数被定义为删除;否则,它被定义为默认(8.4)。 [...]

Trio没有明确声明任何复制构造函数。根据第12段。在C++ 11标准的8/2,事实上:

甲非模板构造用于类X是拷贝构造如果它的第一个参数是X型&,常量X &,易失性X &的或const挥发性X &,并且或者有没有其他参数,否则所有其他参数都默认参数(8.3.6)

因此,您明确提供的构造是拷贝构造函数和应不是禁止隐式生成拷贝构造函数。

VC10可能会误解您作为拷贝构造函数提供的构造函数,因此不会隐式生成。因为上面写的是什么,但是,这种行为是不正确一个和资格作为错误。(*)

作为一个侧面说明,你的代码编译上铛3.2,GCC 4.7.2,以及ICC 13.0罚款。 1。

UPDATE:

我试图模仿与不涉及std::tuple<>简单的数据结构的问题,我失败了。因此,这个错误不仅仅是由于你的构造函数被VC10误解为显式拷贝构造函数。但是,这并不能改变VC10行为不正确的事实。

+1

+1为彻底和参考标准。 – pstrjds 2013-02-20 19:19:34

+0

工作。我为Trio添加了一个显式拷贝构造函数,现在它编译得很好。谢谢!!! – Aaron 2013-02-20 19:21:38

+0

@Aaron:很高兴帮助:-) – 2013-02-20 19:31:23

1

看起来这仅仅是在VS2010的问题。我没有看看是否存在关于它的错误。这将编译VS2012和gcc-4.7.2

+0

谢谢。我不知道VS2010为什么不为Trio生成一个拷贝构造函数,但是如果没有明确的编译器,它肯定不会编译。 – Aaron 2013-02-20 19:23:22