std :: set :: insert()可以调用赋值运算符吗?

时间:2014-04-04 10:44:21

标签: c++ c++11 stl

我有一个带有自定义赋值运算符的类,故意引入控制副作用。

如果我有std::set这些元素,我想知道是否可以使用insert调用赋值运算符。

即:

class A
{
public:
    A & operator=(A const & rhs)
    {
        // custom assignment operator with deliberate side effects
        // Could this be called with use of std::set::insert()?
    }
};

std::set<A> a;

// Is it possible with this, or any use of "insert", that
// the assignment operator will ever be called?

a.insert(A());

是否可以使用std::set::insert

调用赋值运算符

2 个答案:

答案 0 :(得分:3)

在预C ++ 11中,它理论上可以。毫无疑问,C ++ 11禁止它 因为实际上没有实现它。在C ++ 11中, std::set的成员不必支持任务。 在pre-C ++ 11中,支持概念的一些实现可能会 有代码使用赋值,作为检查的方法 你的类支持它,但它应该是非评估的 上下文,因此实际上不会调用操作符。

答案 1 :(得分:1)

C ++ 11标准要求与std::set::insert一起使用的类型为“CopyInsertable” “,”MoveInsertable“或”EmplaceConstructible“取决于您使用的插入功能(23.2.3 / 4)。

这例如定义为:

  

T是EmplaceConstructible进入X的args,对于零个或多个参数args,意味着以下表达式格式正确:allocator_traits<A>::construct(m, p, args);(23.2.1 / 13)

在所有三种情况下,默认行为是std::allocator,它使用了新的位置(17.6.3.5/2):

::new((void*)c)A(forward<Args>(args)...)

根据insert函数,在我们的例子中,argsA类型的表达式,类型为A的rvalue或其他一些参数。但在所有情况下都使用构造函数或复制构造函数,而不是赋值运算符。

这就是标准所说的(和GCC 4.6.3一样)。即使没有理由使用赋值运算符,一些编译器仍然可以使用它。所以我建议不要过分依赖它。