Sign in to follow this  
SuperFist

Properties in ... VC++ - please help

Recommended Posts

Hi folks. I'm using properties in VC++ by: _declspec(property) language extension. The goal i want to achieve is something i saw in C#:
 WindowsControl.Items.Add(...);
 WindowsControl.Items[6].Text = "...";

As you can see - property "Items" can be use as single property or array of properties. How can i make something like that in C++ using _declspec ? I tried this code:
class CTest
{
private:
	vector<int> vec;

public:
	_declspec(property(get=GetVector)) vector<int> propVector;
	_declspec(property(get=GetElement)) int propVector[];

	vector<int>& GetVector()
	{ return vec; }

	int GetElement(int index)
	{ return vec[index]; }
};

but i get: "error C2371: 'CTest::propVector' : redefinition; different basic types" Lets suppose I remove: "_declspec(property(get=GetElement)) int propVector[];" from the code - becouse vector<int> have "operator[]" and i try this:
CTest Obj;
cout << Obj.propVector[3];

I get: "error C2660: 'CTest::GetVector' : function does not take 1 arguments" The proper code:
CTest Obj;
cout << Obj.propVector.operator[](3);

Question: How do it like in C# ?

Share this post


Link to post
Share on other sites
Quote:

but i get: "error C2371: 'CTest::propVector' : redefinition; different basic types"

This is being generated because you have two versions of propVector (there's a clue in the error message), one is a vector<int> and the other an int[]. Call one a propVector and the other propVectorElement to sort this out.
Quote:

I get: "error C2660: 'CTest::GetVector' : function does not take 1 arguments"

The __cdecl(property (...)) is specific to VC so the rules that define how it works is totally arbitrary. It seems that the conversion from:

i=obj.property;

to

i = obj.property_getter ();

occurs before anything else (highest precedence) and that the conversion will consume trailing indexers as part of the expansion, regardless of the declaration:

i=obj.property [index];

becomes:

i=obj.property_getter (index);

even if no [] is appended to the __cdecl statement. This would explain the second error. Your solution works as it separates the [] from the property so the first expansion is used. This may also work:

i=(obj.property)[index];

although I haven't tried it.
Quote:

Question: How do it like in C# ?

The simple answer: use C#. C++ language extensions like this tend to be a bit 'hacky' since the language was never defined to have properties like the C# ones. A bit of template trickery can sort of do the job (search these forums for similar threads).

Skizz

Share this post


Link to post
Share on other sites
Hi Skizz.

Yes I know the origins of those errors. I showed them to ilustrate the problem.
But i think those VC++ properties should be cleverest.

For example:

Obj.Item[45] ...

When compiler see this code and can't find Item array property he should try overwrite it to:

Obj.Item.operator[](45)

It's a pitty that VC team didn't thought about this.

Anyway thanks for help.

Share this post


Link to post
Share on other sites
I am not familiar with the properties, so I would "simply" define custom operators, = and [].


class Dog {
public:
Dog() : myValue(0) {}

const int operator=(int value) {
for (int i = 0; i < myCats.size(); ++i) {
myCats[i] = value;
}
return myValue = value;
}

int& operator[](int index) {
while (myCats.size() <= index) {
myCats.push_back(myValue);
}
return myCats[index];
}

private:
int myValue;
std::vector<int> myCats;
};


You can use operator = to assign a value to all the sub items, and set the default value that will be assigned to the new items.
The operator [] automatically create the object you ask for, and can be used both for read and write. If you define two operators [], one for read and one for write, you may no more need myValue;


Dog Douglas;
Douglas[2] = 3;
Douglas = 5;
Douglas[5] = 1;


Hope it helps more than switch to C#, which has to be pronounced c... s... h... i... :)

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