const_cast in c++ -getting errors - c++

include "stdafx.h"
#include <iostream>
using namespace std;
class Foo{
public:
void func()
{
cout<<"Hello!!"<<endl;
}
};
void some_func(const Foo &f)
{
//f.func();
Foo &fr=const_cast<Foo&>(f);
fr.func();
}
int main()
{
some_func(Foo &f); //if const declared will add the no of errors from 2 to 3
return 0;
}
How to invoke the some_func(const Foo &f)...If i declare the const before Foo parameter in main it shows me error...
But if i'm using the code above i'm getting 2 errors..
output:
1>------ Build started: Project: const_cast, Configuration: Debug Win32 ------
1>Compiling...
1>const_cast.cpp
1>c:\documents and settings\beata\my documents\visual studio 2008\projects\const_cast\const_cast\const_cast.cpp(24) : error C2065: 'f' : undeclared identifier
1>c:\documents and settings\beata\my documents\visual studio 2008\projects\const_cast\const_cast\const_cast.cpp(24) : error C2275: 'Foo' : illegal use of this type as an expression
1> c:\documents and settings\beata\my documents\visual studio 2008\projects\const_cast\const_cast\const_cast.cpp(8) : see declaration of 'Foo'
1>Build log was saved at "file://c:\Documents and Settings\beata\My Documents\Visual Studio 2008\Projects\const_cast\const_cast\Debug\BuildLog.htm"
1>const_cast - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Your problem is probably with main()
int main()
{
Foo f;
some_func(f);
return 0;
}
You need to declare f before you can use it.

int main()
{
Foo f;
some_func(f);
return 0;
}

some_func(Foo &f); looks something like a declaration and something like a function call. If you meant a function call you just pass an object of the appropriate type to the function. E.g.
Foo f;
some_func(f);
or if you want to pass an unnamed temporary (legal because the function takes a const reference):
some_func(Foo());

The problen you're seeing is that you haven't labled the func function call as const to indicate to the compiler that it does not modify visible state. That is,
class Foo{
public:
void func() const{
std::cout << "Hello World!" << std::end;
}
};
will work fine. You put the const at the end of the function calls when they do not modify state (not completely true but more advanced for this post.)
So if you want to pass an object by const ref, you will only ever be able to call methods on it that have been declared non-state modifying. Please don't use const_cast unless you absolutely have to.
Also, don't forget to declare a variable of type Foo in your main body.

some_func(Foo &f); //if const declared will add the no of errors from 2 to 3
Wrong syntax.
Here is what you should be doing:
Foo f; //f is an object of type Foo
some_func(f); //pass the object to the function.

Related

Error making tuple containing a unique_ptr

I am trying to create a function func that returns an std::tuple of an std::unique_ptr<A> and a double. However, when I try to create the tuple I receive errors. The code follows:
#include <tuple>
#include <memory>
class A {
public:
A() : data (3){}
private:
double data;
};
std::tuple<std::unique_ptr<A>, double> func(double num) {
std::unique_ptr<A> a = std::make_unique<A>();
std::tuple<std::unique_ptr<A>, double> temp = std::make_tuple(a, num); // ERROR MESSAGE C
return temp;
}
int main() {
return 0;
}
This code produces the following 4 errors in Visual Studio.
Error message A:
tuple(827,18): error C2440: '<function-style-cast>': cannot convert from 'initializer list' to '_Ttype'
Error message B:
tuple(825,83): message : No constructor could take the source type, or constructor overload resolution was ambiguous
Error message C:
Source.cpp(14): message : see reference to function template instantiation 'std::tuple<std::unique_ptr<A,std::default_delete<A>>,double> std::make_tuple<std::unique_ptr<A,std::default_delete<A>>&,double&>(std::unique_ptr<A,std::default_delete<A>> &,double &)' being compiled
Error message D:
tuple(827,12): error C2064: term does not evaluate to a function taking 2 arguments
First, what is the cause of this error? Second, is the A associated with a being placed on the heap?
A std::unique_ptr is not copyable. You are attempting to copy a std::unique_ptr to the tuple, and that will not work. The compiler error message is kind of cryptic, IMO, but that is basically what seems to be the problem.
However, a std::unique_ptr is moveable, thus you can use std::move:
std::tuple<std::unique_ptr<A>, double> temp = std::make_tuple(std::move(a), num);

Get the return type of a method from a member function pointer

I'm trying to declare a variable so that its type is the same as the return type of a member function to which I have a member function pointer.
class Widget {
public:
std::chrono::milliseconds Foo();
};
For example, given a member function pointer fn which points to Widget::Foo,
how would I declare a variable blah so that it gets Widget::Foo's return type (std::chrono::milliseconds)?
I found some promising guidance from a blog post that uses result_of from <type_traits> along with decltype, but I can't seem to get it to work.
auto fn = &Widget::Foo;
Widget w;
std::result_of<decltype((w.*fn)())>::type blah;
This approach makes sense to me, but VC++ 2013 doesn't like it.
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap(58): error C2064: term does not evaluate to a function taking 0 arguments
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap(118) : see reference to class template instantiation 'std::_Result_of<_Fty,>' being compiled
with
[
_Fty=std::chrono::milliseconds (__cdecl Widget::* )(void)
]
scratch.cpp(24) : see reference to class template instantiation 'std::result_of<std::chrono::milliseconds (__cdecl Widget::* (void))(void)>' being compiled
I don't know if I'm doing something wrong or if this is something that VC++ doesn't handle yet (or both!). The only clue I see in the error message is the __cdecl. Shouldn't the calling convention be __thiscall?
decltype((w.*fn)()) blah;
Or
std::result_of<decltype(fn)(Widget)>::type blah;
Don't know why it works with:
std::result_of<decltype(fn)(Widget)>::type blah;
But I think in brackets should be a pointer to Widget. Because the first member parameter is hidden 'this', a pointer to object
std::result_of<decltype(fn)(Widget*)>::type blah;
class Widget
{
public:
virtual int foo() = 0;
};
int Widget::foo() { }
int main() {
// Your code goes here
auto fn = &Widget::foo;
std::result_of<decltype(fn)(Widget*)>::type blah = 5;
std::cout << blah;
return 0;
}
// output: 5
Also we can't create objects of abstract classes, so code won't compile, if Widget will be an abstract class and not its pointer will be in the brackets
std::result_of<decltype(fn)(Widget)>::type blah = 5;
Compile error:
error: cannot declare parameter to be of abstract type 'Widget'
std::result_of<decltype(fn)(Widget)>::type blah = 5;//
error: incomplete type 'std::result_of<int (Widget::*(Widget))()>' used in nested name specifier
std::result_of<decltype(fn)(Widget)>::type blah = 5;//

Array of Pointers assigning value

Works:
int GlobalVar = 5;
int * LPVar[] = {&GlobalVar};
Doesn't work:
int GlobalVar = 5;
int * LPVar[]; // int * LPVar[1] doesn't work too
LPVar[0] = &GlobalVar; // errors here
------ Build started: Project: pointers, Configuration: Release Win32 ------ Compiling... ilovpointers.cpp .\ilovpointers.cpp(9) : error C2466: cannot allocate an array of constant size 0
.\ilovpointers.cpp(9) : error C4430: missing type specifier - int
assumed. Note: C++ does not support default-int .\ilovpointers.cpp(9)
: error C2040: 'LPVar' : 'int []' differs in levels of indirection
from 'int *[1]' .\ilovpointers.cpp(9) : error C2440: 'initializing' :
cannot convert from 'int *' to 'int []'
There are no conversions to array types, although there are conversions to references or pointers to arrays Build log was saved at
"file://f:\Visual Studio
C++\Project1\pointers\pointers\Release\BuildLog.htm" pointers - 4
error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
EDIT:
I solved but got question.
#include <iostream>
#include <stdio.h>
using namespace std;
int GlobalVar = 5;
int * LPVar[1];
void main()
{
LPVar[0] = &GlobalVar;
printf("%i", *LPVar[0]);
cin.get();
}
LPVar is a global array so why it didn't work when I have put it just after definition?
Is the code at file scope?
The answer appears to be yes given the updated code fragment.
If so, you can't have random assignments like LPVar[0] = &GlobalVar; written at file scope. You can only have declarations (without initializers) or definitions (optionally with initializers) at file scope.
In your question, this works (as indeed it should), because there are two variable definitions with initializers.
int GlobalVar = 5;
int *LPVar[] = {&GlobalVar};
This code does not work (as indeed it shouldn't), because the third line is an assignment statement and not a declaration or definition:
int GlobalVar = 5;
int *LPVar[]; // Declaration, not definition
LPVar[0] = &GlobalVar; // Assignment is not allowed outside a function body
Variant:
int GlobalVar = 5;
int *LPVar[1]; // Definition without initializer
LPVar[0] = &GlobalVar; // Assignment is not allowed outside a function body

Pointer to member, within class

I am trying create a typedef for a template that needs a pointer to member, from within a class. The best way to describe it is to show the minimal sample code:
template<typename T, int T::*MV>
struct Bar
{
const int &value(const T &t) const
{
return (t.*MV);
}
};
struct Foo
{
int baz;
typedef Bar<Foo, &Foo::baz> GetBaz; // Compiler error
};
typedef Bar<Foo, &Foo::baz> GetFooBaz; // Compiles just fine
int main(int argc, char* argv[])
{
Foo f = { 42 };
Foo::GetBaz b; // Fails to compile
GetFooBaz b2; // Fine
int val = b.value(f); // Fails to compile because of above
int val2 = b2.value(f); // Fine
}
I am not necessarily dead-set on getting access to a member pointer in this way, I would be fine just knowing the offset to the variable and having the Bar::value function perform trickery.
As a last resort, I suppose I could use a traits class since the would move the definition outside of the class, but I would prefer to be able to declare the typedef near the variable being used.
And, to answer the "why would you want to do that" question, this is all for an IoC container that closely represents the way MEF (C# works).
The specific compiler I am using is VC12, but it would be nice if VC11 supported it as well.
Thanks
EDIT:
Here are the error messages
1>------ Build started: Project: MemVarBug, Configuration: Debug Win32 ------
1> MemVarBug.cpp
1>memvarbug.cpp(20): error C2327: 'Foo::baz' : is not a type name, static, or enumerator
1>memvarbug.cpp(20): error C2065: 'baz' : undeclared identifier
1>memvarbug.cpp(20): error C2975: 'MV' : invalid template argument for 'Bar', expected compile-time constant expression
1> memvarbug.cpp(7) : see declaration of 'MV'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
you can do the following trick:
declare baz to be int[1];
array of size one, in this case calling baz will return the pointer and calling *baz will return the value.

C++ Garbage collection, templates and operator overriding - can't understand why it throws an error

I am trying to compile a file which defines a garbage collection template and several supporting classes with use of operator overloading. I've tried to run this through MSVC++ 2008, and the compile stops at this particular class:
// (The collector defines gc_object_generic_base which
// inherits from gc_object_generic_base and optionally adds
// collector-specific properties.)
template<class garbage_collector>
class gc_object_base : public garbage_collector::gc_object_collector_base {
public:
gc_object_base() {
garbage_collector::constructing_gc_object_base(this);
}
static void* operator new(size_t sz,
block_construction_locker_base* lock = block_construction_locker<garbage_collector>().get_this())
{
return garbage_collector::allocate(sz, lock);
}
static void operator delete(void* p, block_construction_locker_base* lock) {
return garbage_collector::deallocate(p);
}
static void operator delete(void* p) {
return garbage_collector::deallocate(p);
}
private:
// TODO: are arrays worth implementing?
static void* operator new[](size_t sz) {
assert(0);
return 0;
}
};
Truncated output for brevity's sake:
2>------ Build started: Project: Test, Configuration: Debug Win32 ------
2>Compiling...
2>FlashTest.cc
2>C:\test\gameswf\base\tu_gc.h(133) : error C2059: syntax error : 'string'
2> C:\test\gameswf\base\tu_gc.h(151) : see reference to class template instantiation 'tu_gc::gc_object_base' being compiled
2>C:\test\gameswf\base\tu_gc.h(135) : error C2091: function returns function
2>C:\test\gameswf\base\tu_gc.h(135) : error C2802: static member 'operator new' has no formal parameters
2>C:\test\gameswf\base\tu_gc.h(135) : error C2333: 'tu_gc::gc_object_base::operator new' : error in function declaration; skipping function body
Any ideas on where I should start looking at?
I just had the same pattern of errors in a different project. It seems to happen when someone has done this somewhere:
#define new new(someArgs, someMoreArgs, etc)
It's targeted at simple 'new' expressions, but it breaks down if anyone tries to declare any more 'operator new' thingies.
In the opening lines
template<class garbage_collector>
class gc_object_base : public garbage_collector::gc_object_collector_base {
garbage_collector appears twice here, once as the template parameter and another as an outer-class to gc_object_collector_base, but as it is a template parameter does it not require "typename" here thus:
template<class garbage_collector>
class gc_object_base : public typename garbage_collector::gc_object_collector_base {
There is no mention of string in your code, that I can see. But I would start by ensuring that you first #include <string> before your class delcaration, and then make sure you use std::string as your declarator, rather than just string.