
Im trying to initialize boost variant ( from boost_1_33_1) as below in MSVC8 variant<char* , int> v ; v = 2; I find that the the direct_assigner always fails and returns false in assign method of variant. template <class .... class variant { ........... template <typename T> void assign(const T& rhs) { // If direct T-to-T assignment is not possible... detail::variant::direct_assigner<const T> direct_assign(rhs); /// ---------------(1) if (this->apply_visitor(direct_assign) == false)<--------- the variant template arguments digging deeper I found that the reason is in direct_assigner visitor interface template <typename T> class direct_assigner : public static_visitor<bool> { private: // representation T& rhs_; // <--------------------------------------- (2) .... ... #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200) public: // visitor interface bool operator()(T& lhs) //<--------------------(3) is never called { lhs = rhs_; return true; } template <typename U> bool operator()(U&) { return false; ////<---------we always hit this } The operator() in statement (3) is never called since T is of const type ( as set in statement (1) above in assign method of variant). bit variant template argument is not const. Shouldnt 'const' be prepended to statement (2) instead of prepending it in (1)? Thanks, Arun

Hi Arun, Thank you for noting and taking the time to track down this issue! I believe you are correct. I just wrote the following simple test: #include <iostream> #include "boost/variant.hpp" static int copyCount = 0; static int assignCount = 0; struct MyType { MyType() {} MyType(const MyType&) { ++copyCount; } MyType& operator=(const MyType&) { ++assignCount; return *this; } }; int main() { boost::variant<MyType> var; var = MyType(); std::cout << "copied: " << copyCount << "; assigned: " << assignCount << std::endl; } The expected result would be copied: 0; assigned: 1 but due to the defect you noted, the actual result in fact is copied: 1; assigned: 1 For GCC, the fix is exactly as you suggest. In the next day or two I will make the change so that it can be tested with other compilers. As you can see in the code, there is already a workaround for VC6, so you never know what might break :) Eric arun.s wrote:
Im trying to initialize boost variant ( from boost_1_33_1) as below in MSVC8
variant<char* , int> v ; v = 2;
I find that the the direct_assigner always fails and returns false in assign method of variant.
template <class .... class variant { ........... template <typename T> void assign(const T& rhs) { // If direct T-to-T assignment is not possible... detail::variant::direct_assigner<const T> direct_assign(rhs); /// ---------------(1) if (this->apply_visitor(direct_assign) == false)<---------
the variant template arguments
digging deeper I found that the reason is in direct_assigner visitor interface
template <typename T> class direct_assigner : public static_visitor<bool> {
private: // representation
T& rhs_; // <--------------------------------------- (2)
.... ...
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
public: // visitor interface
bool operator()(T& lhs) //<--------------------(3) is never called { lhs = rhs_; return true; }
template <typename U> bool operator()(U&) { return false; ////<---------we always hit this }
The operator() in statement (3) is never called since T is of const type ( as set in statement (1) above in assign method of variant). bit variant template argument is not const.
Shouldnt 'const' be prepended to statement (2) instead of prepending it in (1)?
Thanks, Arun _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
arun.s
-
Eric Friedman