I've just started learning D. In C++ there is :: (Scope resolution operator) to access global variable from the function if both global & local varible have same name. But how to do this in D language? Consider this program.
import std.stdio;
int a;
int main(string[] args)
{
int a=3;
writeln("D is nice");
static int i;
writeln("value of i is: ",i);
writeln("value of a is: ",a);
// writeln("value of ::a is: ",::a); compiler error here
return 0;
}
How can I print the value of global variable a from within main() function? Does D provide such kind of operator?
D uses a leading dot for that:
writeln("value of .a is: ",.a);
In the spec: http://dlang.org/module.html - section "Module Scope Operator"
Related
I have a really strange problem. I can't modify the object I am pointing to with a shared_ptr.
Example code:
#include<memory>
#include<iostream>
using namespace std;
class foo
{
public:
int asd;
foo(){}
~foo(){}
};
void d(shared_ptr<foo> c)
{
c->asd = 3;
}
void main()
{
foo a;
a.asd = 5;
d(make_shared<foo>(a));
cout<<a.asd; //asd is still 5
}
As far as I know you can access the object pointed to by the shared_ptr by using the "->" operator, so what am I doing wrong here? How can I change the asd variable inside the class via the shared pointer?
// create a temporary object by copying a
// the shared pointer you pass to d function actually points to this temporary object
d(make_shared<foo>(a));
// allocate and store foo object in shared_ptr instead
auto p_a(make_shared<foo>());
p_a->asd = 3;
d(p_a);
... so what am I doing wrong here?
From cppreference on std::make_shared [emphasis mine]:
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
Constructs an object of type T and wraps it in a std::shared_ptr
using args as the parameter list for the constructor of T.
In your case, you supply an instance of foo as argument to std::make_shared, which will be used when constructing a new object of type foo; i.e., making use of the default supplied copy CTOR of foo (foo(const foo&)). This new object will be a temporary and only live for the call to d(...).
From bruce eckel --" although u should always declare functions by including header file , functions declarations aren't' essential in c . Its possible in c but not cpp to call a function u havent declared. This is a dangerous practise because the c compiler may assume that a function that u call with an integer argument has an argument list containing integer even if it may actually contain float . This can produce bugs" my question is that even if a function is not declared , during its definition we have to mention the data type of arguments [ VOID FUNC( INT A)] , so how can a compiler assumes a float to be an integer??
The compiler makes assumption on supplied parameters if a function is not declared or defined prior to the point the assumption should be made. Try the following code and check the result (checked with gcc):
#include <stdio.h>
int main (int argc, char * argv[])
{
x(1);
x(1.);
x(1);
return 0;
}
void x(double y)
{
printf ("%f\n", y);
}
I have the following code:
#include <iostream>
#include <utility>
#include <map>
using namespace std;
int main()
{
map<int, map<string, int> > mapa;
// way A
mapa[10]["aaa"] = 20;
// way B -> Compilation Error
pair<int, pair<string, int> > par(10, make_pair("aaa", 20));
mapa.insert(par);
return 0;
}
I know that "way A" of populating the map works.
I want to use "way B" but it throw a compilation Error:
error: no matching function for call to ‘std::map, int>::map(const std::pair, int>&)’
How can I populate the nested map with insert operator.
Pd: I don't use [] operator because it requires the default constructor to be defined which I don't have since I am using time_period objects from Boost.
Well the type of your map is map of (int -> map of (string -> int)) but you are trying to insert an entry of type map of (int -> pair (string, int)). A pair is not a map, thus the error.
EDIT:
According to the documentation, a call to map's [] operator is equivalent to a series of other operations:
mapped_type& operator[] (const key_type& k);
A call to this function is equivalent to:
(*((this->insert(make_pair(k,mapped_type()))).first)).second
so in your case, the call mapa[10]["aaa"] = 20; is equivalent to:
(*(( (*((mapa.insert(make_pair(10,map<string, int>()))).first)).second
.insert(make_pair("aaa",20))).first)).second
but I believe if either key 10 or aaa exist, no element will be inserted in the map. I suggest you read the docs thoroughly and test for the expected behavior.
Using Qt, I want this code to work:
QList<QPair<QString, QString>> list;
foreach (QPair<QString, QString> pair, list)
{
}
instead, I get the error:
'pair' : undeclared identifier
Using a typedef I can make it work, but this is not what I want (unless this is the only thing that works):
typedef QPair<QString, QString> MyPair;
QList<MyPair> list;
foreach (MyPair pair, list)
{
}
Can anyone explain why the first foreach doesn't compile?
it's not the foreach error. It's declaration error. You declared list like this:
QList<QPair<QString, QString>> list;
while it should this way:
QList<QPair<QString, QString> > list;
Just declare QPair outside of loop:
QPair<QString,QString> pair;
foreach(pair,list){
}
It is not possible to use template classes inside qt foreach statement which contains more than one template parameter, because comma separator conflicts with comma separator inside macros.
#define add( a, b ) (a + b)
template < typename T1, typename T2 >
struct DATA
{
static const T1 val1 = 1;
static const T2 val2 = 2;
};
// Usage
const int c = add( 1, 2 ); // OK
const int d = add( DATA< int, int >::val1 , DATA< int, int >::val2 ); // FAIL
because macros add will interpret "DATA< int" as first argument, and " int >::val1" as second, and so on.
Some explanation with above answer... if your compiler accept
QList<QPair<QString, QString>> list;
giving no error on such declaration, reasons for topic caster error is different and indeed has to do with a fact that declaration must be done outside of foreach() loop. That's explained in QT documentation.
regarding >> and > >... that's old story and latest GCC (so linux/mac) consider it to be a syntax mistake, because it's not conforming standard. >> in GCC manner is treated as operator with all follow-up errors..
first and foremost sorry for my bad english, I'm no english native =/
I have a vector of pointers directing at my base class A which is filled by classes B and C.
B and C are polymorphic classes from A, which have only one more method, setTest().
Now I want to call a method from B/C through the vector:
vector (A*) vec;
vec.push_back(new classB());
vec.push_back(new classC());
for(int i=0;i<3;++i)
vec[i]->setTest(true);
But the compiler says there is no method setTest() in my baseclass A.
Any ideas how I can fix this?
Since compiler "think" that deals with A, it cannot deduce that method setTest exists.
To resolve this problem you can do following:
Add abstract method to A:
virtual void setTest(bool value) = 0;
Update
There is another way. Let's create helper interface D with only one method:
struct D
{
virtual void setTest(bool value) = 0;
};
Than using multiple inheritance change signature of B and C:
class B : public A, public D
{
virtual void setTest(bool value)
{
//your impl goes here...
}
};
//do the same with impl of C
And at last let's change iteration:
for(int i=0;i<3;++i)
((D*)vec[i])->setTest(true);
Simple casting allows call expected method. BUT!!! if vector can contains instances of A than it will fail, so using dynamic_cast helps:
for(int i=0;i<3;++i)
{
D *check_inst = dynamic_cast<D*>(vec[i]);
if( check_inst)
check_inst->setTest(true);
}