Jump to content
  • Advertisement
Sign in to follow this  
Grumple

C++ Visual Studio std::vector::emplace_back c++11 vs c++17

Recommended Posts

I have a general c++ template programming question...I've tried to setup a class that used a nested template type T, along with variadic template arguments for a constructor of T, to ensure I can add items to a custom container class without any unnecessary heap usage/copy/move operations.  

Here is my test container code, using perfect forwarding and std::vector::emplace_back() to create items 'in-place' with little overhead (TemplateContainerTest.h):

#pragma once

#include <vector>
#include <unordered_map>
#include <utility>

template <typename T>
class TemplateContainerTest
{
public:
	TemplateContainerTest() = default;
	virtual ~TemplateContainerTest() = default;

	template<typename... ItemArgs>
	void AddItem( ItemArgs&&... itemArgs )
	{
		m_Container.emplace_back( std::forward<ItemArgs>( itemArgs )... );
	}
protected:
	template <typename T>
	class ItemTracker 
	{
	public:
		template<typename... ItemArgs >
		ItemTracker( ItemArgs&&... itemArgs ):
			m_Item( std::forward<ItemArgs>( itemArgs )... )
		{
		}

		bool m_IsValid = false;

		T m_Item;
	};

	std::vector< ItemTracker<T> > m_Container;
};

And here is some code to exercise the template above (main.cpp):

#include "stdafx.h"
#include <stdint.h>

#include "CNTemplateContainer.h"

class TestItemOfInterest
{
public:
	TestItemOfInterest( uint32_t itemVal ):
		m_ItemVal( itemVal )
	{
	}

	TestItemOfInterest( TestItemOfInterest && other )
	{
		m_ItemVal = other.m_ItemVal;

		other.m_ItemVal = 0;
	}

	TestItemOfInterest() = default;
	virtual ~TestItemOfInterest() = default;

	uint32_t GetVal() { return m_ItemVal; }
protected:
	uint32_t m_ItemVal = 0;
};


int _tmain(int argc, _TCHAR* argv[])
{
	TemplateContainerTest<TestItemOfInterest> tmpContainer;

	tmpContainer.AddItem( 42 );

	return 0;
}

Here is the kicker: in Visual Studio 2013, the code above fails to compile with the following error:

templatecontainertest.h(28): error C2664: 'TestItemOfInterest::TestItemOfInterest(const TestItemOfInterest &)' : cannot convert argument 1 from 'TemplateContainerTest<TestItemOfInterest>::ItemTracker<T>' to 'uint32_t'

However, in Visual Studio 2017 it compiles fine.   For some reason, the perfect forwarding mechanism of Visual Studio 2013 seems to try to send the 'ItemTracker' into the T() constructor instead of just the arguments from outside.   I see that the VS 2017 std::vector::emplace_back signature/implementation changed, but I can't understand why it works now/didn't work before...

Any insight would be appreciated as I don't trust this at all without understanding the underpinning issues...

Edited by Grumple

Share this post


Link to post
Share on other sites
Advertisement

Might have been a bug in 2013 that was fixed for 2015/17.  VS 2013 didn't fully support C++11 features.  I don't even think 2017 is fully compliant yet.  Though they're close from what I read.  Any reason you need to test this on a 4 year old compiler?  Just curious.

Share this post


Link to post
Share on other sites

Yeah that could very well be it, just looking to rule out that it 'shouldn't compile' for some reason.

I have no good excuse for the old compiler other than this being the first issue that has really made me feel the need to change.  Having seen this code compile on a friends VS2017 setup, I will likely be be updating asap...

Thanks!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!