I am not able to understand why why move constructor is not getting called while move assignment is able to while if I use move function in Line X , it used to call the move constructor . Can anybody tell what will be the way or syntax to call the move constructor .
#include <iostream>
#include <cstring>
#include <algorithm>
#include <memory>
using namespace std;
class String
{
char *s;
int len;
public:
String():s(nullptr),len(0){ cout<<"Default "; }
String(char *p)
{
if(p)
{
len = strlen(p);
s = new char[len];
strcpy(s,p);
}
else
{
s = nullptr;
len = 0;
}
cout<<"Raw ";
}
String(String &p)
{
if(p.s)
{
len = strlen(p.s);
s = new char[len];
strcpy(s,p.s);
}
else
{
s = nullptr;
len = 0;
}
cout<<"Copy ";
}
String & operator = (const String & p)
{
if(this != &p)
{
delete []s;
s = nullptr;
len = 0;
if(p.len)
{
len = p.len;
s = new char[len];
strcpy(s,p.s);
}
}
cout<<"Assignment ";
return *this;
}
String( String && p):s(nullptr),len(0) // move constructor
{
len = p.len;
s = p.s;
p.s = nullptr;
p.len = 0;
cout<<"Move Copy ";
}
String & operator = (String && p) // move assignment
{
if(this != &p)
{
delete []s;
len = 0;
s = nullptr;
if(p.len)
{
len = p.len;
s = p.s;
p.s = nullptr;
p.len = 0;
}
}
cout<<"Move Assignment ";
return *this;
}
~String() { delete []s; cout<<"Destructor \n"; }
void show() { cout<<s<<endl; }
};
int main()
{
String s1("Something ");
String s2(s1);
s1.show();
s2.show();
String s4(String("Nothing ")); // Line X
s4.show();
String s5;
s5 = String(s2);
s5.show();
return 0;
}
OUTPUT:
Raw Copy Something
Something
Raw Nothing
Default Copy Move Assignment Destructor
Something
Destructor
Destructor
Destructor
Destructor
It's the second variant of the copy elision explained here: http://en.cppreference.com/w/cpp/language/copy_elision.
http://coliru.stacked-crooked.com/a/17f811a0be4ecba3
Note -fno-elide-constructors, it disables the optimization in g++.
Output:
Copy Something
Something
Raw Move Copy Move Copy Destructor
Destructor
Nothing
Default Copy Move Assignment Destructor
Something
Destructor
Destructor
Destructor
Destructor
Related
I am trying to transfer the elements from a source stack to a destination stack. And for that i am using some variables and making sure that get transfered into the destination stack in the same order as they were in the source stack. I wrote the following code
#include <iostream>
#include <stack>
using namespace std;
template <typename S>
void transferByVar(stack<S> &source, stack<S> &dest)
{
int var = 0;
S topVal;
if (source.empty())
return;
else if (source.size() == 1)
{
dest.push(source.top());
source.pop();
}
int size = source.size();
while (count != size)
{
topVal = source.top();
source.pop();
while (source.size() != count)
{
dest.push(source.top());
source.pop();
}
source.push(topVal);
while (!dest.empty())
{
source.push(dest.top());
dest.pop();
}
++count;
}
}
int main()
{
stack <int> s1;
stack<int> s2;
s1.push(0);
s1.push(1);
s1.push(2);
s1.push(3);
s1.push(4);
s1.push(5);
s1.push(6);
s1.push(7);
s1.push(8);
s1.push(9);
transferByVar(s1, s2);
int size = s2.size();
for (int i = 0; i < size; i++)
{
cout << s2.top() << " ";
s2.pop();
}
return 0;
}
but it gives me an error of C2563: mismatch of formal parameter list. What can I do to fix this?
This little program has to write an xml file.
Building the code I get the following error:
K:\Sergio\cpp\xml\sergio\cbp6s\main.cpp|32|error: 'base_tag' is an inaccessible base of 'tag'
In short, I have two classes derived from base_tag (xml_declaration and tag) and I want insert (or emplace) in a std::map some std::pair elements.
Building, the first insert works (std::pair<order::declaration, xml_declaration>), but the second fails (std::pair<order::root, tag_object>).
Between the object are derived from base_tag
Where am I wrong?
File tag.hpp :
#ifndef _TAG_HPP_
#define _TAG_HPP_
#include <string>
#include <vector>
#include <utility>
enum class tag_type
{
closing = -1,
autoclosed = 0,
opening = 1
};
using attribute = std::pair<std::string, std::string>;
class base_tag
{
public:
base_tag();
virtual ~base_tag();
virtual std::string get();
bool attribute_exists(std::string);
std::string get_attribute_value(std::string name);
bool add_attribute(std::string name, std::string value);
protected:
std::vector<std::pair<std::string, std::string>> _attributes;
};
// ------------------------------------------------------------
class xml_declaration : public base_tag
{
public:
xml_declaration();
~xml_declaration();
std::string get();
};
// ----------------------------------------------------------
class tag : base_tag
{
public:
tag(std::string name);
tag(std::string name, tag_type tt );
std::string get();
void set_ident(size_t ident);
protected:
std::string _name;
tag_type _tt;
};
#endif // _TAG_HPP_
File tag.cpp
#include "tag.hpp"
base_tag::base_tag()
{
}
base_tag::~base_tag()
{
_attributes.clear();
}
bool base_tag::attribute_exists(std::string name)
{
bool res = false;
for(auto & i : _attributes)
{
if (i.first == name)
res = true;
}
return res;
}
bool base_tag::add_attribute(std::string name, std::string value)
{
bool res = false;
if(!attribute_exists(name))
{
attribute a = std::make_pair(name, value);
_attributes.push_back(a);
res = true;
}
return res;
}
std::string base_tag::get()
{
return u8"<invalid_tag/>";
}
// -------------------------------------------------------
xml_declaration::xml_declaration(): base_tag()
{
add_attribute("version", "1.0");
add_attribute("encoding", "UTF-8");
add_attribute("standalone", "yes");
}
xml_declaration::~xml_declaration()
{ }
std::string xml_declaration::get()
{
std::string res = u8"<?xml";
for(auto & i : _attributes)
{
res.push_back(' ');
res += i.first;
res += u8"=\"";
res += i.second;
res += u8"\"";
}
res += u8" ?>";
return res;
}
// -------------------------------------------------------------
tag::tag(std::string name):base_tag(), _name(name)
{
_tt = tag_type::autoclosed;
}
tag::tag(std::string name, tag_type tt ): base_tag(), _name(name),
_tt(tt)
{ }
std::string tag::get()
{
std::string res = u8"";
bool with_attributes = !(_attributes.empty());
switch(_tt)
{
case tag_type::autoclosed : {
res = u8"<";
res += _name;
if(with_attributes)
{
for(auto & i : _attributes)
{
res.push_back(' ');
res += i.first;
res += u8"=\"";
res += i.second;
res += u8"\"";
}
};
res += u8"/>";
break;
}
case tag_type::opening : {
res = u8"<";
res += _name;
for(auto & i : _attributes)
{
res.push_back(' ');
res += i.first;
res += u8"=\"";
res += i.second;
res += u8"\"";
}
res += u8">";
break;
}
case tag_type::closing : {
res = u8"</";
res += _name;
res.push_back('>');
}
default : break;
}
return res;
}
File main.cpp
#include <iostream>
#include <map>
#include <utility>
#include "tag.hpp"
using namespace std;
enum class order
{
declaration = 0,
root = 1,
file_version = 4,
project = 10,
project_closing = 998,
root_closing = 1000
};
int main()
{
std::map<order, base_tag> tree;
xml_declaration decl;
cout << decl.get() << endl;
tag t1("project_file", tag_type::opening);
tag t2("project_file", tag_type::closing);
tree.insert(std::pair<order, base_tag>(order::declaration,
decl));
tree.insert(std::pair<order, base_tag>(order::root, t1));
tree.insert(std::pair<order, base_tag>(order::root, t2));
// tree.emplace(std::pair<order, base_tag>(order::root_closing, t1));
cout << tree.size() << endl;
return 0;
}
I'm using Code::Blocks with GCC 5.1.0 (on Windows 10).
As the error message says, tag inherits base_tag privately. If you change its headline into
class tag: public base_tag;
(same as your xml_declaration which inherits base_tag publicly) then it will officially be-a base tag.
A more serious problem is that you try to store instances of inherited classes in a container of a base class by value. What happens then is, objects get sliced and lose their whole derived functionality; you put an object of a derived class into a map, but you actually store an object of a based class in it (that's the reason some people tend to say polymorphic base classes should necessarily be abstract.) Use (smart) pointers or reference_wrappers as map's mapped type.
I keep getting this error. I know what function causes it, but don't know how to fix it. Looking up online from this post saying:
You need to pass a pointer to a dynamically allocated object, or make your own insde your chainLink class.
However, as I try to pass a string pointer. error still popping up. Here is my code.
#include <iostream>
#include "MWTNode.h"
#include "MWT.h"
using namespace std;
int main() {
MWT t;
string str ="abc";
string* strPtr = &str;
t.insert(strPtr);
std::cout << "Hello, World!" << std::endl;
return 0;
}
#include "MWTNode.h"
class MWT {
public:
MWTNode *root;
string find(const string &);
void insert(const string* string);
};
void MWT::insert(const string* word) {
MWTNode* curr = root;
MWTNode newNode;
string w = *word;
for (int i = 0; i < word->length(); i++) {
const char c = w[i];
if (curr->children.find(c) == curr->children.end()){
//curr->children[c]= MWTNode();
//node->frequency=node->frequency+1;
}
curr = &(curr->children[c]);
}
curr->flag = true;
}
#include <unordered_map>
#include <vector>
#include <string>
#include <sstream>
#include <set>
using namespace std;
class MWTNode {
public:
unordered_map<char, MWTNode> children;
string value;
bool flag;
int frequency;
MWTNode(const string &);
MWTNode(const char c);
MWTNode();
void setFrequency ();
int getFrequency ();
};
MWTNode::MWTNode(const string &val) {
value = val;
flag = false;
frequency = 0;
}
MWTNode::MWTNode(const char c) {
value =c;
flag = false;
frequency = 0;
}
MWTNode::MWTNode() {
value ="";
flag = false;
frequency = 0;
}
Lets highlight a few lines of the code you show
class MWT {
public:
MWTNode *root;
// ...
};
In that you declare the member variable root as a pointer.
void MWT::insert(const string* word) {
MWTNode* curr = root;
// ...
}
In the above you make curr point to where root is pointing.
But you never make root point anywhere! The MWT::root variable is uninitialized and will have an indeterminate value. Using this pointer in any way without initialization will lead to undefined behavior.
And yes you use this pointer, as you dereference curr inside the MWT::insert function.
It's a little unclear what you're doing (to me) but you need to make sure that root (and therefore curr) is a valid pointer before attempting to dereference it.
The common "solution" to use GetProcAddress with C++ is "extern "C", but that breaks overloading. Name mangling allows multiple functions to co-exist, as long as their signature differs. But is there a way to find these mangled names for GetProcAddress?
The VC++ compiler knows its own name mangling scheme, so why not use that? Inside template<typename T> T GetProcAddress(HMODULE h, const char* name), the macro __FUNCDNAME__ contains the mangled name of GetProcAddress. That includes the T part. So, inside GetProcAddress<void(*)(int), we have a substring with the mangled name of void(*)(int). From that, we can trivially derive the mangled name of void foo(int);
This code relies on the VC++ macro __FUNCDNAME__. For MinGW you'd need to base this on __PRETTY_FUNCTION__ instead.
FARPROC GetProcAddress_CppImpl(HMODULE h, const char* name, std::string const& Signature)
{
// The signature of T appears twice in the signature of T GetProcAddress<T>(HMODULE, const char*)
size_t len = Signature.find("##YA");
std::string templateParam = Signature.substr(0, len);
std::string returnType = Signature.substr(len+4);
returnType.resize(templateParam.size()); // Strip off our own arguments (HMODULE and const char*)
assert(templateParam == returnType);
// templateParam and returnType are _pointers_ to functions (P6), so adjust to function type (Y)
std::string funName = "?" + std::string(name) + "##Y" + templateParam.substr(2);
return ::GetProcAddress(h, funName.c_str());
}
template <typename T>
T GetProcAddress(HMODULE h, const char* name)
{
// Get our own signature. We use `const char* name` to keep it simple.
std::string Signature = __FUNCDNAME__ + 18; // Ignore prefix "??$GetProcAddress#"
return reinterpret_cast<T>(GetProcAddress_CppImpl(h, name, Signature));
}
// Showing the result
struct Dummy { };
__declspec(dllexport) void foo( const char* s)
{
std::cout << s;
}
__declspec(dllexport) void foo( int i, Dummy )
{
std::cout << "Overloaded foo(), got " << i << std::endl;
}
__declspec(dllexport) void foo( std::string const& s )
{
std::cout << "Overloaded foo(), got " << s << std::endl;
}
__declspec(dllexport) int foo( std::map<std::string, double> volatile& )
{
std::cout << "Overloaded foo(), complex type\n";
return 42;
}
int main()
{
HMODULE h = GetModuleHandleW(0);
foo("Hello, ");
auto pFoo1 = GetProcAddress<void (*)( const char*)>(h, "foo");
// This templated version of GetProcAddress is typesafe: You can't pass
// a float to pFoo1. That is a compile-time error.
pFoo1(" world\n");
auto pFoo2 = GetProcAddress<void (*)( int, Dummy )>(h, "foo");
pFoo2(42, Dummy()); // Again, typesafe.
auto pFoo3 = GetProcAddress<void (*)( std::string const& )>(h, "foo");
pFoo3("std::string overload\n");
auto pFoo4 = GetProcAddress<int (*)( std::map<std::string, double> volatile& )>(h, "foo");
// pFoo4 != NULL, this overload exists.
auto pFoo5 = GetProcAddress<void (*)( float )>(h, "foo");
// pFoo5==NULL - no such overload.
}
Use dumpbin /exports 'file.dll' to get the decorated / undecorated name of all the symbols.
It's impossible to do it just by using GetProcAddress. However, one way to do it would be to enumerate all the exported functions for that particular module, and do a pattern matching to find all the mangled names.
More specifically, refer to this answer here. The only change you will need to make would be to pass in TRUE for MappedAsImage parameter and the return value of GetModuleHandle for Base parameter to ImageDirectoryEntryToData function call.
void EnumerateExportedFunctions(HMODULE hModule, vector<string>& slListOfDllFunctions)
{
DWORD *dNameRVAs(0);
_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory;
unsigned long cDirSize;
_LOADED_IMAGE LoadedImage;
string sName;
slListOfDllFunctions.clear();
ImageExportDirectory = (_IMAGE_EXPORT_DIRECTORY*)
ImageDirectoryEntryToData(hModule,
TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &cDirSize);
if (ImageExportDirectory != NULL)
{
dNameRVAs = (DWORD *)ImageRvaToVa(LoadedImage.FileHeader,
LoadedImage.MappedAddress,
ImageExportDirectory->AddressOfNames, NULL);
for(size_t i = 0; i < ImageExportDirectory->NumberOfNames; i++)
{
sName = (char *)ImageRvaToVa(LoadedImage.FileHeader,
LoadedImage.MappedAddress,
dNameRVAs[i], NULL);
slListOfDllFunctions.push_back(sName);
}
}
}
I can't quite fathom why you'd ever want/need a constexpr version of MSalters' solution, but here it is, complete with namespace mangling. Use as
using F = int(double*);
constexpr auto f = mangled::name<F>([]{ return "foo::bar::frobnicate"; });
constexpr const char* cstr = f.data();
where F is the function signature and foo::bar::frobnicate is the (possibly qualified) name of the function.
#include<string_view>
#include<array>
namespace mangled
{
namespace detail
{
template<typename F>
inline constexpr std::string_view suffix()
{
auto str = std::string_view(__FUNCDNAME__);
return str.substr(14, str.size() - 87);
}
template<typename L>
struct constexpr_string
{
constexpr constexpr_string(L) {}
static constexpr std::string_view data = L{}();
};
template<typename Name>
inline constexpr int qualifiers()
{
int i = -2, count = -1;
while(i != std::string_view::npos)
{
i = Name::data.find("::", i + 2);
count++;
}
return count;
}
template<typename Name>
inline constexpr auto split()
{
std::array<std::string_view, qualifiers<Name>() + 1> arr = {};
int prev = -2;
for(int i = arr.size() - 1; i > 0; i--)
{
int cur = Name::data.find("::", prev + 2);
arr[i] = Name::data.substr(prev + 2, cur - prev - 2);
prev = cur;
}
arr[0] = Name::data.substr(prev + 2);
return arr;
}
template<typename F, typename Name>
struct name_builder
{
static constexpr auto suf = detail::suffix<F>();
static constexpr auto toks = split<Name>();
static constexpr auto len = Name::data.size() + suf.size() - toks.size() + 6;
static constexpr auto str = [] {
std::array<char, len> arr = {};
arr[0] = '?';
int i = 1;
for(int t = 0; t < toks.size(); t++)
{
if(t > 0)
arr[i++] = '#';
for(auto c : toks[t])
arr[i++] = c;
}
arr[i++] = '#';
arr[i++] = '#';
arr[i++] = 'Y';
for(auto c : suf)
arr[i++] = c;
return arr;
}();
};
}
template<typename F, typename LambdaString>
inline constexpr std::string_view name(LambdaString)
{
using Cs = detail::constexpr_string<LambdaString>;
using N = detail::name_builder<F, Cs>;
return {N::str.data(), N::len};
}
}
GodBolt
I'm trying to compile a code in Visual Studio, but I keep getting the following error:
Error 4 error C3867: 'MindSet::Form1::handleDataValueFunc': function call missing argument list; use '&MindSet::Form1::handleDataValueFunc' to create a pointer to member c:\documents and settings\licap\desktop\mindset\mindset\mindset\Form1.h 122 1 MindSet
This is my code
#pragma endregion
void handleDataValueFunc(unsigned char extendedCodeLevel, unsigned char code,
unsigned char valueLength, const unsigned char *value, void *customData)
{
FILE *arq1;
FILE *arq2;
FILE *arq3;
arq1 = fopen("raw.txt","a");
arq2 = fopen("atencao.txt","a");
arq3 = fopen("meditacao.txt","a");
if (extendedCodeLevel == 0 && code == RAW_WAVE_CODE)
{
short rawValue = ((value[0] << 8) & 0xff00) | (0x00ff & value[1]);
printf("%d\n", rawValue);
fprintf(arq1,"%d\n",rawValue);
}
if (extendedCodeLevel == 0 && code == ATTENTION_LEVEL_CODE)
{
short attentionValue = (value[0] & 0xFF);
printf("%d\n", attentionValue);
fprintf(arq2,"%d\n",attentionValue);
}
if (extendedCodeLevel == 0 && code == MEDITATION_LEVEL_CODE)
{
short meditationValue = (value[0] & 0xFF);
printf("%d\n", meditationValue);
fprintf(arq3,"%d\n",meditationValue);
}
fclose(arq1);
fclose(arq2);
fclose(arq3);
}
private: System::Void IniciarCaptura_Click(System::Object^ sender, System::EventArgs^ e) {
SerialPort* port = new SerialPortW32();
if (port->open())
{
/* Initialize ThinkGear stream parser */
ThinkGearStreamParser parser;
THINKGEAR_initParser(&parser, PARSER_TYPE_PACKETS, handleDataValueFunc, NULL);
unsigned char byteRead;
for (int i = 0; i < 100000; i++)
{
if (port->read(&byteRead, 1) == 1)
{
THINKGEAR_parseByte(&parser, byteRead);
fflush(stdout);
}
else
{
//cerr << "Erro na leitura da porta" << endl;
break;
}
}
port->close();
}
else
{
//cout << port->getErrorMessage() << endl;
}
delete port;
//return 0;
}
};
}
I've already tried to add a "&" before "handleDataValueFunc", but it only returns another error message. Can anybody help?
You will have to use gcroot See http://msdn.microsoft.com/en-us/library/481fa11f.aspx
struct nativeMindSetFormHandle
{
nativeMindSetFormHandle(MindSet::Form1 ^ h) : handle(h) {}
gcroot<MindSet::Form1 ^> handle;
};
static void handleDataValueFuncProxy(unsigned char extendedCodeLevel,
unsigned char code, unsigned char valueLength, const unsigned char *value,
void *customData)
{
static_cast<nativeMindSetFormHandle *>(customData)->handle->handleDataValueFunc(extendedCodeLevel, code, valueLength, value, NULL);
}
And update IniciarCaptura_Click to include:
nativeMindSetFromHandle * nativeHandle = new nativeMindSetFormHandle(this);
THINKGEAR_initParser(&parser, PARSER_TYPE_PACKETS, handleDataValueFuncProxy, nativeHandle);
And don't forget to delete nativeHandle when you are done.