Aar*_*ron 6 c++ inheritance tuples vector c++11
我想创建一个包含3个值的结构:一个字符串和两个整数.该字符串是必需的,但是int中的任何一个(或两个)都是可选的,如果未指定,则默认为-1.
但是,我想我会尝试使用std :: tuple,而不是使用结构.为了合并两个整数的可选性,我设置了一个"Trio"类,它继承自std :: tuple,如下所示:
#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)
{
}
};
Run Code Online (Sandbox Code Playgroud)
然后我通过将一些Trio对象推入std :: vector来测试Trio类:
#include <vector>
int main(void)
{
std::vector<Trio> trios;
Trio trio("trio1", 1, 1);
trios.push_back(trio);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它在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
Run Code Online (Sandbox Code Playgroud)
有谁知道我在这里做错了什么?我有没有看到明显的东西?或许,我是否严重滥用std :: tuple的用法?
谢谢,
亚伦
这是VC10的一个错误.
VC10抱怨,因为你的类不似乎有一个拷贝构造函数.因此,为了复制类型的值Trio,它会尝试将它们转换为string,这是您提供的构造函数接受的(其他参数可以被赋予默认值).这就是你得到的错误:
无法将参数1从'const Trio'转换为'const std :: basic_string <_Elem,_Traits,_Ax>&'
您可以通过显式添加复制构造函数来验证这确实是发生了什么,并观察错误消失:
Trio(Trio const& t) { *this = t; }
Run Code Online (Sandbox Code Playgroud)
现在VC10很满意,因为它看到了一个复制构造函数,并且代码编译得很好.
然而,当用户没有显式提供拷贝构造函数时,编译器应该隐式生成一个拷贝构造函数.根据C++ 11标准的第12.8/7段:
如果类定义没有显式声明复制构造函数,则会隐式声明一个.如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数被定义为已删除; 否则,它被定义为默认值(8.4).[...]
类Trio没有显式声明任何复制构造函数.根据C++ 11标准的第12.8/2段,实际上:
如果X类的第一个参数是X&,const X&,volatile X&或const volatile X&,并且没有其他参数或者所有其他参数都有默认参数,则类X的非模板构造函数是一个复制构造函数(8.3.6) )
因此,您明确提供的构造是不是一个拷贝构造函数,应该不会抑制拷贝构造函数的隐代.
VC10可能会误解您作为复制构造函数提供的构造函数,因此不会隐式生成一个构造函数.但是,由于上面所写的内容,此行为是不正确的,并且有资格作为错误.(*)
作为旁注,您的代码在Clang 3.2,GCC 4.7.2和ICC 13.0.1上编译良好.
更新:
我尝试使用更简单的数据结构来重现问题std::tuple<>,但是我失败了.因此,错误不仅仅是由于VC10将构造函数误解为显式复制构造函数.但是,这并没有改变VC10行为不正确的事实.
| 归档时间: |
|
| 查看次数: |
1124 次 |
| 最近记录: |