mirror of
https://github.com/boostorg/move.git
synced 2025-07-29 20:07:13 +02:00
34
doc/move.qbk
34
doc/move.qbk
@ -661,6 +661,32 @@ An alternative is to implement a single `operator =()` for copyable and movable
|
||||
However, "pass by value" is not optimal for classes (like containers, strings, etc.) that reuse resources
|
||||
(like previously allocated memory) when x is assigned from a lvalue.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:templated_assignment_operator Templated assignment operator in copyable and movable types]
|
||||
|
||||
|
||||
[import ../example/doc_template_assign.cpp]
|
||||
|
||||
Given a movable and copyable class, if a templated assignment operator (*) is added:
|
||||
|
||||
[template_assign_example_foo_bar]
|
||||
|
||||
C++98 and C++11 compilers will behave different when assigning from a `[const] Foo` lvalue:
|
||||
|
||||
[template_assign_example_main]
|
||||
|
||||
This different behaviour is a side-effect of the move emulation that can't be easily avoided by
|
||||
[*Boost.Move]. One workaround is to SFINAE-out the templated assignment operator with `disable_if`:
|
||||
|
||||
[c++]
|
||||
|
||||
template<class U> // Modified templated assignment
|
||||
typename boost::disable_if<boost::is_same<U, Foo>, Foo&>::type
|
||||
operator=(const U& rhs)
|
||||
{ i = -rhs.i; return *this; } //(2)
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
@ -762,6 +788,14 @@ Many thanks to all boosters that have tested, reviewed and improved the library.
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_62 Boost 1.62 Release]
|
||||
|
||||
* Documented new limitations reported in Trac tickets
|
||||
[@https://svn.boost.org/trac/boost/ticket/12194 #12194 ['"Copy assignment on moveable and copyable classes uses wrong type"]] and
|
||||
[@https://svn.boost.org/trac/boost/ticket/12307 #12307 ['"Copy assignment on moveable and copyable classes uses wrong type"]].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_61 Boost 1.61 Release]
|
||||
|
||||
* Experimental: asymptotically optimal bufferless merge and sort algorithms: [funcref boost::movelib::adaptive_merge adaptive_merge]
|
||||
|
98
example/doc_template_assign.cpp
Normal file
98
example/doc_template_assign.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/move for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/detail/meta_utils_core.hpp>
|
||||
|
||||
#include <boost/move/move.hpp>
|
||||
|
||||
//[template_assign_example_foo_bar
|
||||
|
||||
class Foo
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(Foo)
|
||||
|
||||
public:
|
||||
int i;
|
||||
explicit Foo(int val) : i(val) {}
|
||||
|
||||
Foo(BOOST_RV_REF(Foo) obj) : i(obj.i) {}
|
||||
|
||||
Foo& operator=(BOOST_RV_REF(Foo) rhs)
|
||||
{ i = rhs.i; rhs.i = 0; return *this; }
|
||||
|
||||
Foo& operator=(BOOST_COPY_ASSIGN_REF(Foo) rhs)
|
||||
{ i = rhs.i; return *this; } //(1)
|
||||
|
||||
template<class U> //(*) TEMPLATED ASSIGNMENT, potential problem
|
||||
//<-
|
||||
#if 1
|
||||
typename ::boost::move_detail::disable_if_same<U, Foo, Foo&>::type
|
||||
operator=(const U& rhs)
|
||||
#else
|
||||
//->
|
||||
Foo& operator=(const U& rhs)
|
||||
//<-
|
||||
#endif
|
||||
//->
|
||||
{ i = -rhs.i; return *this; } //(2)
|
||||
};
|
||||
//]
|
||||
|
||||
struct Bar
|
||||
{
|
||||
int i;
|
||||
explicit Bar(int val) : i(val) {}
|
||||
};
|
||||
|
||||
|
||||
//<-
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
//->
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
//[template_assign_example_main
|
||||
Foo foo1(1);
|
||||
//<-
|
||||
assert(foo1.i == 1);
|
||||
//->
|
||||
Foo foo2(2);
|
||||
//<-
|
||||
assert(foo2.i == 2);
|
||||
Bar bar(3);
|
||||
assert(bar.i == 3);
|
||||
//->
|
||||
foo2 = foo1; // Calls (1) in C++11 but (2) in C++98
|
||||
//<-
|
||||
assert(foo2.i == 1);
|
||||
assert(foo1.i == 1); //Fails in C++98 unless workaround is applied
|
||||
foo1 = bar;
|
||||
assert(foo1.i == -3);
|
||||
foo2 = boost::move(foo1);
|
||||
assert(foo1.i == 0);
|
||||
assert(foo2.i == -3);
|
||||
//->
|
||||
const Foo foo5(5);
|
||||
foo2 = foo5; // Calls (1) in C++11 but (2) in C++98
|
||||
//<-
|
||||
assert(foo2.i == 5); //Fails in C++98 unless workaround is applied
|
||||
assert(foo5.i == 5);
|
||||
//->
|
||||
//]
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
@ -114,6 +114,18 @@ struct is_same<T, T>
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// enable_if_same
|
||||
//////////////////////////////////////
|
||||
template <class T, class U, class R = void>
|
||||
struct enable_if_same : enable_if<is_same<T, U>, R> {};
|
||||
|
||||
//////////////////////////////////////
|
||||
// disable_if_same
|
||||
//////////////////////////////////////
|
||||
template <class T, class U, class R = void>
|
||||
struct disable_if_same : disable_if<is_same<T, U>, R> {};
|
||||
|
||||
} //namespace move_detail {
|
||||
} //namespace boost {
|
||||
|
||||
|
@ -127,6 +127,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_merge_test", "adap
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_template_assign", "doc_template_assign.vcproj", "{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
@ -263,6 +267,10 @@ Global
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.Build.0 = Debug|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.ActiveCfg = Release|Win32
|
||||
{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.Build.0 = Release|Win32
|
||||
{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Debug.ActiveCfg = Debug|Win32
|
||||
{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Debug.Build.0 = Debug|Win32
|
||||
{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Release.ActiveCfg = Release|Win32
|
||||
{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionItems) = postSolution
|
||||
..\..\..\..\boost\move\algo\adaptive_merge.hpp = ..\..\..\..\boost\move\algo\adaptive_merge.hpp
|
||||
|
134
proj/vc7ide/doc_template_assign.vcproj
Normal file
134
proj/vc7ide/doc_template_assign.vcproj
Normal file
@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="doc_template_assign"
|
||||
ProjectGUID="{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Debug"
|
||||
IntermediateDirectory="Debug/doc_template_assign"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
DisableLanguageExtensions="FALSE"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_template_assign_d.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/doc_template_assign.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../Bin/Win32/Release"
|
||||
IntermediateDirectory="Release/doc_template_assign"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
|
||||
RuntimeLibrary="2"
|
||||
TreatWChar_tAsBuiltInType="TRUE"
|
||||
ForceConformanceInForLoopScope="FALSE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="winmm.lib"
|
||||
OutputFile="$(OutDir)/doc_template_assign.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="../../../../stage/lib"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{475F3C87-6465-7BC5-05A6-2454C0A2A2CF}">
|
||||
<File
|
||||
RelativePath="..\..\example\doc_template_assign.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
Reference in New Issue
Block a user