I'm trying to figure out a problem I have in my project, and I have simplified it down to this little bit of code that generates the C2664 error. I don't understand the error message, could anyone help me to understand? I've googled, and I've looked through 2 C++ books and this code is exactly what is listed in them, but it does not work for me.
Thanks.
#include <memory>
struct A
{
int b;
};
int main(int argc, char ** argv)
{
A a;
std::unique_ptr<A> a_ptr = std::make_unique<A>(new A);
return 0;
}
And here is the error:
1>------ Build started: Project: Project1, Configuration: Debug Win32 ------
1>main.cpp
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(2585): error C2664: 'A::A(const A &)': cannot convert argument 1 from 'A *' to 'A &&'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(2584): note: Reason: cannot convert from 'A *' to 'A'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(2584): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>d:\users\aksel\documents\visual studio 2017\projects\project1\project1\main.cpp(21): note: see reference to function template instantiation 'std::unique_ptr<A,std::default_delete<_Ty>> std::make_unique<A,A*,0>(A *&&)' being compiled
1> with
1> [
1> _Ty=A
1> ]
1>Done building project "Project1.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The argument to make_unique is the argument to a T constructor, not a pointer to a T instance, just use the regular unique_ptr ctor if you already have a pointer to a T.
Related
I made a custom allocator, but my code didn't compile on msvc and I'm not sure if my implementation satisfies the Allocator requirement (disregarding actual behavior of function implementations here). Here is a minimal example that reproduces the error on Visual Studio (16.11 P1 and 16.10):
#include <memory>
#include <vector>
template <typename T>
class Allocator
{
public:
using value_type = T;
[[nodiscard]]
T* allocate(std::size_t n)
{
return nullptr;
}
void deallocate(T* x, std::size_t n)
{
}
constexpr bool operator==(const Allocator& other) const noexcept
{
return true;
}
constexpr bool operator!=(const Allocator& other) const noexcept
{
return !(*this == other);
}
};
int main()
{
using Alloc = Allocator<int>;
using Vec = std::vector<int, Alloc>;
auto vec = Vec();
}
Godbolt isn't complaining for any major compiler but their msvc version is a little behind I think.
To me this looks like a compiler bug in msvc but I want to make sure before I open a ticket.
This is the compiler output:
Build started...
1>------ Build started: Project: Project1, Configuration: Debug x64 ------
1>main.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(714,27): error C2440: 'static_cast': cannot convert from 'Allocator<int>' to 'Allocator<_Newfirst>'
1> with
1> [
1> _Newfirst=std::_Container_proxy
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(714,27): message : No constructor could take the source type, or constructor overload resolution was ambiguous
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(711): message : while compiling class template member function 'std::vector<int,Alloc>::~vector(void) noexcept'
1>C:\code\dumpster\Project1\Project1\main.cpp(36): message : see reference to function template instantiation 'std::vector<int,Alloc>::~vector(void) noexcept' being compiled
1>C:\code\dumpster\Project1\Project1\main.cpp(36): message : see reference to class template instantiation 'std::vector<int,Alloc>' being compiled
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(714,25): error C2530: '_Alproxy': references must be initialized
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(715,1): error C3536: '_Alproxy': cannot be used before it is initialized
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(715,9): error C2672: '_Delete_plain_internal': no matching overloaded function found
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(715,1): error C2893: Failed to specialize function template 'void std::_Delete_plain_internal(_Alloc &,_Alloc::value_type *const ) noexcept'
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\xmemory(998): message : see declaration of 'std::_Delete_plain_internal'
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(715,1): message : With the following template arguments:
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.29.30129\include\vector(715,1): message : '_Alloc=int'
1>Done building project "Project1.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Edit
I opened a bug ticket for the msvc devs.
It does not.
An allocator rebound to a different value type must be constructible from the original allocator - this is the A a(b) row in the requirements you linked.
Your type fails that requirement.
This question already has answers here:
Why is this code trying to call the copy constructor?
(2 answers)
Closed 4 years ago.
It's taken me a while, but I've finally constructed a minimal example with illustrates the problem I'm having.
#include <memory>
#include <vector>
class Thing
{
};
class Box
{
public:
std::vector<std::unique_ptr<Thing>> Things;
static Box MakeBox() {Box b; return b;}
};
My real program is obviously quite a lot more complicated than this.
GCC 4.8.3 happily compiles this. It also compiles the real application, which works perfectly.
Visual Studio 2012 insists that this code is not correct, giving me error C2248 on line 606 of vc\include\xmemory0. If I wade through several miles of compiler output, I discover the real source of the error is line 11 in the above example. (The line that defines Things.) VS also refuses to compile my real application, with the same error.
So, is this code correct or not? If it's not correct, then why does GCC accept it? And how to I make it correct? If it is correct, then why won't VS compile it? Is there some way I can unconditionally force VS to actually compile my program?
Output from VS:
1>------ Build started: Project: TestUniquePtr, Configuration: Debug Win32 ------
1> Main.cpp
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(606): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1> with
1> [
1> _Ty=Thing
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
1> with
1> [
1> _Ty=Thing
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
1> with
1> [
1> _Ty=std::unique_ptr<Thing>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(751) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<Thing>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits(743) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<Thing>
1> ]
1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector(655) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled
1> with
1> [
1> _Ty=std::allocator<std::unique_ptr<Thing>>
1> ]
1> d:\projects\c++\testuniqueptr\testuniqueptr\main.cpp(11) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=std::unique_ptr<Thing>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Your problem isn't std::unique_ptr but std::vector.
Your compiler comes with an old version of std::vector that requires the element type to be copyable.
The return by value (return b;) should invoke a move of the vector, but your std::vector doesn't implement move.
std::unique_ptr is moveable but not copyable, therefore it doesn't meet the pre-C++11 requirements for being used in std::vector... a requirement which still applies to VC++ 2012.
Your best option is to use a newer compiler and standard library. One that supports move semantics on std::vector.
Otherwise you might make some progress by eliminating the copy of std::vector, for example, by having MakeBox fill in an output argument rather than returning a new object.
static void MakeBox(Box& b) { /* fill Things in b provided by caller */ }
That's probably an exercise in futility though, because whenever the vector needs to grow, it has to relocate the existing elements to new storage, and with incomplete move support, it will try to copy those.
The problem is that Box has no move constructor, thus returning a Box requires it to have a copy constructor (which it can't because unique_ptr is not copyable). All you have to do is define a move constructor for Box:
Box::Box(Box&& other)
: Things(std::move(other.Things))
{
}
With more recent editions, the compiler will generate the move constructor for you.
After downloading this https://github.com/pybind/pybind11/archive/v2.2.3.zip
and creating a simple cpp file:
#include <pybind11/pybind11.h>
int add(int i, int j) { return i + j; }
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
}
with
I get this error
Error C2446 '<': no conversion from 'unsigned __int64' to 'unsigned __int64 *' in c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector line 2326
Would anybody know what this could be referring to, and possibly how to fix it?
As requested, here the full error log:
1>------ Rebuild All started: Project: Test_CreatePythonBindings, Configuration: Debug x64 ------
1>example.cpp
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector(2326): error C2446: '<': no conversion from 'unsigned __int64' to 'unsigned __int64 *'
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector(2326): note: Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector(2325): note: while compiling class template member function 'std::_Vb_const_iterator<std::_Wrap_alloc<std::allocator<std::_Vbase>>> &std::_Vb_const_iterator<std::_Wrap_alloc<std::allocator<std::_Vbase>>>::operator +=(__int64)'
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector(2545): note: see reference to function template instantiation 'std::_Vb_const_iterator<std::_Wrap_alloc<std::allocator<std::_Vbase>>> &std::_Vb_const_iterator<std::_Wrap_alloc<std::allocator<std::_Vbase>>>::operator +=(__int64)' being compiled
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector(2490): note: see reference to class template instantiation 'std::_Vb_const_iterator<std::_Wrap_alloc<std::allocator<std::_Vbase>>>' being compiled
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector(3094): note: see reference to class template instantiation 'std::_Vb_iterator<std::_Wrap_alloc<std::allocator<std::_Vbase>>>' being compiled
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector(3093): note: while compiling class template member function 'void std::vector<bool,std::allocator<_Ty>>::push_back(const bool &)'
1> with
1> [
1> _Ty=bool
1> ]
1>c:\pybind11-2.2.3\include\pybind11\pybind11.h(513): note: see reference to function template instantiation 'void std::vector<bool,std::allocator<_Ty>>::push_back(const bool &)' being compiled
1> with
1> [
1> _Ty=bool
1> ]
1>c:\pybind11-2.2.3\include\pybind11\cast.h(1806): note: see reference to class template instantiation 'std::vector<bool,std::allocator<_Ty>>' being compiled
1> with
1> [
1> _Ty=bool
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\vector(2326): warning C4554: '&': check operator precedence for possible error; use parentheses to clarify precedence
1>Done building project "Test_CreatePythonBindings.vcxproj" -- FAILED.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
It appears to be a VS 2017 issue related to
std::vector<bool>
Separate question asked here:
Pushback on vector<bool> fails - VS 2017
I'm trying to use my game engine into an external project. Everything works fine but I have a problem when I'm trying to create a custom component (That inherits from ABhaviour which is an abstract class representing a component that can be activated/disabled).
GameObject.h (exported with __declspec(dllexport))
// [...]
template <typename Class, typename ... Args>
std::shared_ptr<Class> GameObject::AddComponent(Args... args)
{
auto newComp = std::make_shared<Class>(std::forward<Args>(args)...);
m_components[typeid(*newComp).hash_code()] = newComp;
m_components[typeid(*newComp).hash_code()]->SetOwner(*this);
return newComp;
}
// [...]
In an other project (That use my game engine), I'm trying to create the custom ABehaviour :
PlayerController.h
#pragma once
#include <ElkGameEngine/Objects/Components/Behaviours/ABehaviour.h>
class PlayerController :ElkGameEngine::Objects::Components::Behaviours::ABehaviour
{
PlayerController() = default;
~PlayerController() = default;
void Update();
};
After that I add my custom component onto my "Player" GameObject :
Main.cpp
#include <ElkGameEngine/ElkGameEngine.h>
#include <ElkGameEngine/Objects/AObject.h>
#include <ElkGameEngine/Objects/Components/AComponent.h>
#include "PlayerController.h"
using namespace ElkGameEngine::Objects::Components;
using namespace ElkGameEngine::Objects::Components::Behaviours;
int main()
{
ElkGameEngine::Managers::EngineManager elkGameEngine;
elkGameEngine.GetSceneManager()->CreateScene("ElkCraft");
auto& player = elkGameEngine.GetSceneManager()->CreateEmptyGameObject("Player");
player.AddComponent<PlayerController>(); /* Here is the problem */
while (elkGameEngine.IsRunning())
{
elkGameEngine.PreUpdate();
elkGameEngine.PostUpdate();
}
return EXIT_SUCCESS;
}
Visual Studio is unhappy and print me this :
Severity Code Description Project File Line Suppression State
Error C2440 '<function-style-cast>': cannot convert from 'const std::shared_ptr<PlayerController>' to 'std::shared_ptr<ElkGameEngine::Objects::Components::AComponent>' ElkCraft c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory 1472
Error C2228 left of '.swap' must have class/struct/union ElkCraft c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory 1472
Output window :
1>------ Build started: Project: ElkCraft, Configuration: Debug x64 ------
1>Could Not Find C:\Users\adrie\Desktop\GROUP_2\PFA\ElkCraft\*.dll
1>main.cpp
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1472): error C2440: '<function-style-cast>': cannot convert from 'const std::shared_ptr<PlayerController>' to 'std::shared_ptr<ElkGameEngine::Objects::Components::AComponent>'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1472): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>c:\users\adrie\desktop\group_2\pfa\elkengine\build\elkgameengine\include\elkgameengine\objects\gameobject.h(53): note: see reference to function template instantiation 'std::shared_ptr<ElkGameEngine::Objects::Components::AComponent> &std::shared_ptr<ElkGameEngine::Objects::Components::AComponent>::operator =<PlayerController>(const std::shared_ptr<PlayerController> &) noexcept' being compiled
1>c:\users\adrie\desktop\group_2\pfa\elkengine\build\elkgameengine\include\elkgameengine\objects\gameobject.h(55): note: see reference to function template instantiation 'std::shared_ptr<ElkGameEngine::Objects::Components::AComponent> &std::shared_ptr<ElkGameEngine::Objects::Components::AComponent>::operator =<PlayerController>(const std::shared_ptr<PlayerController> &) noexcept' being compiled
1>c:\users\adrie\desktop\group_2\pfa\elkcraft\sources\main.cpp(18): note: see reference to function template instantiation 'std::shared_ptr<PlayerController> ElkGameEngine::Objects::GameObject::AddComponent<PlayerController,>(void)' being compiled
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1472): error C2228: left of '.swap' must have class/struct/union
1>Generating Code...
1>Compiling...
1>PlayerController.cpp
1>Generating Code...
1>Done building project "ElkCraft.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I think that the problem come from the fact that my game engine (Which is a group of DLL) is exporting a templated method (AddComponent and other ones like GetComponent).
Is it possible to use a templated method from a dll with a class/struct template argument from the project using the dll ?
Am I doing something wrong ?
Do I need to specify something on my PlayerController to make it "known/usable" in the AddComponent method ?
I'm very new to C++/VS and might missing something in the code/configuration of my project.
In my solution I have 2 projects:
first is NTL which I downloaded from https://bitbucket.org/ben_key/ntl, and compiled to a static library NTL.lib.
a 'test' project in which: (1) I added the header files by specifying their directory in the properties->C++->Additional Include Files, (2) in the properties->Linker->Input->Additional Dependencies I added "NTL.lib" (3)copied the NTL.lib file to be in the same directory as the main cpp file of the 'test' project.
My cpp only contains:
#include <NTL/GF2X.h>
int main() {
GF2X P;
return 1;
}
The build gives the output:
1>------ Build started: Project: test, Configuration: Release Win32 ------
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(388,5): warning MSB8028: The intermediate directory (Release\) contains files shared from another project (ntl-test.vcxproj). This can lead to incorrect clean and rebuild behavior.
1> QuickTest.cpp
1>..\tests\QuickTest.cpp(43): warning C4101: 'n' : unreferenced local variable
1>D:\studies\Thesis\NTL-Ben-Key\Include\NTL/vector.h(79): warning C4291: 'void *operator new(size_t,_ntl_vector_placement)' : no matching operator delete found; memory will not be freed if initialization throws an exception
1> D:\studies\Thesis\NTL-Ben-Key\Include\NTL/vector.h(36) : see declaration of 'operator new'
1> D:\studies\Thesis\NTL-Ben-Key\Include\NTL/vector.h(319) : see reference to function template instantiation 'void NTL::BlockConstruct<T>(T *,long)' being compiled
1> with
1> [
1> T=NTL::zz_p
1> ]
1> D:\studies\Thesis\NTL-Ben-Key\Include\NTL/vector.h(291) : while compiling class template member function 'void NTL::Vec<NTL::zz_p>::DoSetLength(long)'
1> D:\studies\Thesis\NTL-Ben-Key\Include\NTL/vector.h(115) : see reference to function template instantiation 'void NTL::Vec<NTL::zz_p>::DoSetLength(long)' being compiled
1> D:\studies\Thesis\NTL-Ben-Key\Include\NTL/vec_lzz_p.h(14) : see reference to class template instantiation 'NTL::Vec<NTL::zz_p>' being compiled
1> MyTest.cpp
1>MyTest.cpp(4): error C2065: 'GF2X' : undeclared identifier
1>MyTest.cpp(4): error C2146: syntax error : missing ';' before identifier 'P'
1>MyTest.cpp(4): error C2065: 'P' : undeclared identifier
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
It is really a simple thing and I didn't figured out what I'm missing.
From NTL/include/NTL/ tools.h:
#define NTL_NAMESPACE NTL
#define NTL_OPEN_NNS namespace NTL_NAMESPACE {
#define NTL_CLOSE_NNS }
So when the preprocessor encounters NTL_OPEN_NNS, as is the case in the include file GF2X.h, it expands it to namespace NTL meaning the GF2X class is declared insided the namespace NTL. In order to use it you need to fully qualify it as NTL::GF2X or use using namespace NTL for discussion about which one look here for example.
Likewise at the end of GF2X.h there is a closing bracket after expanding NTL_CLOSE_NNS