In my code, I am using string IDs. That is good in debug and in code during coding. You can imagine it like this:
MyCar * c = cars->GetCarID("my_car_1");
MyCar * c = cars->GetCarID(variable);
But this is slower in release, because of string - string comparison in GetCarID code.
I would like to have something like this
MyCar * c = cars->GetCarID(CREATE_ID("my_car_1"));
MyCar * c = cars->GetCarID(CREATE_ID(variable));
CREATE_ID - in debug, it will return string that is written in code, in release, it will return int hash or something like that.
How can I achieve this? Or how is this usually solved?
You can wrap your id in a class, something like:
class StringID
{
public:
StringID(const StringID&);
StringID(const char*);
StringID(const std::string&);
...
private:
#if DEBUG
std::string _idAsString;
#endif
int _id;
};
and define common operation for your class, like operator<, operator== and so on. In this way on release build you will have a wrapper over int and on debug build the class will contain the string to make it easier to debug.
For performance reasons you can make id/hash computation constexprand compute it at compile time for string literals (for more info please check this: Computing length of a C string at compile time. Is this really a constexpr?).
With this approach you can catch hash clashes by checking also the strings in debug mode, not only the hashes. As you probably already know, different strings can lead to same hash (unlikely for common english words, but possible) and this will be very difficult to debug without knowing the string that generated the hash.
In debug mode, #define CREATE_ID(x) #x and use cars->GetCarID(CREATE_ID(my_car_1));. In release mode, #define CREATE_ID(x) x, add an enum { my_car_1, ... } and you still use cars->GetCarID(CREATE_ID(my_car_1));
Note that you never use CREATE_ID(variable) but you may use auto variable = CREATE_ID(my_car_id).
You could use enums instead of strings. This way you have readable names for your integers:
enum ID {
my_car_1
, my_train_1
, my_g6_1
};
My approach would be to use enum class. This allows to have typesafe identifier, that is char or int underneath. A simple code example would be:
#include <iostream>
enum class COLOR {
RED
, GREEN
};
std::ostream & operator << (std::ostream & o, const COLOR & a) {
switch(a) {
case COLOR::RED: o << "RED";break;
case COLOR::GREEN: o << "GREEN";break;
default: o << static_cast<int>(a);
}
return o;
}
int main() {
COLOR c = COLOR::RED;
std::cout << c << std::endl;
return 0;
}
The drawback is, that you have to explicitly writeout all identifiers twice - once in class and once in operator.
One of the mayor advantages of enum class is that names are scoped and it does not allow stuff like:
std::string get(COLOR x);
...
get(3); //Compile time error
get(CAR::GOLF);//Compile time error
Judging by your comments on other answers, you can define your own identifier like this:
class MyId {
public:
int id;
static std::unordered_map<int,std::string> names;
};
std::ostream & operator << (std::ostream &o,const MyId & m) {
auto itr = MyId::names.find(m.id);
if(itr!= MyId::names.end()) {
o << itr->second;
} else {
o << "Unknown " << m.id;
}
return o;
}
Its typesafe, theres no more overhead then int, and it is able to survive user input.
Related
The one annoyance I have with the std::string class is that the only ways (that I could figure out after reading cplusplus.com's info about it) to get the location of the last character in the string is (stringVariable.length() - 1) or stringVariable.rfind(stringVariable.back()). It'd be nice if I could just do stringVariable.last(). This is for a function I wrote in a personal project that needs to reference this number of a user's input string.
Some ideas I had were creating a struct that is just a string and has the last() function as a member function, or a class that copies the string class and adds that member. With a struct, I'm not sure how (or if it's possible) to make it so I can make the variable assigned to the type automatically reference the string in it so that I don't need to make a constant member call. I'm taking the second C++ class in school right now, but we haven't touched on C++ classes yet.
I tried reading some guides and answers here about classes, and they don't look all that different from structs, but the more complex stuff in either case was Greek to me. I only learned how to use a struct as a holder for multiple variable types; like the name string and id int for a person, or something like that. I learned from the guides I can put functions in them, and define operator behavior too, but when I tried to define operator behavior for the string struct I made, I couldn't get it to work.
Based on the example I read, I tried:
str &operator=(const str &ing)
{
s = ing.s;
return s;
}
But when I tried to test it by using = to copy a str variable to a string variable I could cout, it errors that str can't be converted to string, so I tried a few adjustments, and after getting errors about the & and such, I ended up with:
string operator=(str ing)
{
return ing.s;
}
Which gets the same error. Here's the full struct test program I'm using:
#include <iostream>
#include <string>
using namespace std;
struct str
{
string s;
string operator=(str ing)
{
return ing.s;
}
int last()
{
return s.length() - 1;
}
};
int main()
{
str ing {"Hello World!"};
string i = ing;
cout << i;
return 0;
}
If I could get the = assignment to work, I'd try to get << and such to work with str, too.
If that doesn't turn out to be possible, my fallback is just using a function like:
int last(string str)
{
return str.length() - 1;
}
Edit: For More Info
I was asked many times in the comments what my actual need is for this. In truth it’s just that it annoys me that it doesn’t have that member function. I’m surprised it wasn’t implemented long ago.
Thanks to the commenters I was able to come up with the diabolical workaround of overloading an operator to make a string able to subtract a function to output the result of a string being input to the function. I used - because I was thinking script notation: stringVariable -l or stringVariable -last. Then I can also just use #define to remove the need for the operator, making it stringVariable last() (“last()” instead of “last” because aesthetic).
Another option I figured out was reversing positions and using #define to make it last stringVariable, or #define in - to make it last in stringVariable. Although the simplest version of the operator function for this by far is just defining a negative string as the int output directly. Not that any of that is really better than just using the function normally, but I enjoyed learning about those features of C++.
The single answerer also consolidated much of the commenters advice and brought it to the next level to give me a more elegant version of the idea I had to create my own class with a string that could do all the string stuff and the extra member. However taking the advice of reexamining my needs I think perhaps ‘string’ isn’t the only option I have for a user input container. I definitely need the int output made by stringVariable.size() - 1 with whatever char array I use (since it’s used in mathematical equations), but maybe a vector or something else could do that already?
I was briefly told about vectors in my previous class, but we weren’t allowed to use them. Since this is for a simulated environment I’m doing on my own (that I might use for the basis of a game some day) I can use anything I want though. I also decided to pull an allnighter last night and just started reading about containers at random on cplusplus.com.
So I’m wondering if perhaps a list or deque could work too. I wasn’t really taught about anything other than string and hardcoded arrays (yet) though. I use the string to store the user’s input to simplify the process of avoiding unforeseeable crashing/errors that come from bad user inputs, then just translate the strings to whatever I need with various functions I've written.
creating a struct that is just a string and has the last() function as a member function
That will work just fine, if you don't mind implementing the interfaces needed to convert between std::string <-> str.
Also, be aware that std::string indexes use std::string::size_type, which is not int. size_type is an unsigned type, typically std::size_t. std::string defines an npos constant to indicate "no index", that is what your last() function should return if the std::string is empty, eg:
std::string::size_type last_index() const
{
return !s.empty() ? s.size() - 1 : std::string::npos;
}
But, if you really want to have last() return an int (ie, your std::string will never exceed 2147483647 characters):
int last_index() const
{
return static_cast<int>(s.size()) - 1;
}
With a struct, I'm not sure how (or if it's possible) to make it so I can make the variable assigned to the type automatically reference the string in it so that I don’t need to make a constant member call.
In short, no.
Based on the example I read, I tried:
str &operator=(const str &ing)
{
s = ing.s;
return s;
}
It needs to return a reference to the str object that is being assigned to, not the std::string member that was actually modified, eg:
str& operator=(const str &rhs)
{
s = rhs.s;
return *this;
}
But when I tried to test it by using = to copy a str variable to a string variable I could cout, it errors that str can't be converted to string
Correct, it can't by default. You need to define a conversion operator for that purpose, eg:
operator std::string() const
{
return s;
}
If I could get the = assignment to work, I'd try to get << and such to work with str, too.
Yes, you should, eg:
std::ostream& operator<<(std::ostream &out, const str &rhs)
{
return out << rhs.s;
}
If that doesn't turn out to be possible, my fallback is just using a function
That is a good idea, eg:
std::string::size_type last_index(const std::string &s)
{
return !s.empty() ? s.size() - 1 : std::string::npos;
}
Or:
int last_index(const str::string &s)
{
return static_cast<int>(s.size()) - 1;
}
Here's the full struct test program I'm using
Try this:
#include <iostream>
#include <string>
using namespace std;
class str
{
private:
string s;
public:
str() = default;
str(const string &s) : s(s) {}
str& operator=(const str &rhs)
{
s = rhs.s;
return *this;
}
operator string() const
{
return s;
}
string::size_type last_index() const
{
return !s.empty() ? s.size() - 1 : string::npos;
}
friend ostream& operator<<(ostream &out, const str &rhs)
{
return out << rhs.s;
}
};
string::size_type last_index(const string &s)
{
return !s.empty() ? s.size() - 1 : string::npos;
}
int main()
{
str ing {"Hello World!"};
cout << ing << endl;
cout << ing.last_index() << endl;
string i = ing;
cout << i << endl;
cout << last_index(i) << endl;
return 0;
}
I'm an absolute newbee when it comes to programming and I'm trying to teach myself the basics by just solving some easy "problems" in C++.
I have searched the web for an exact answer to my question before posting it here and haven't found one so far, however that may be because of (1).
So, what I'm looking for is a way to declare a class member that gets automatically calculated from other members of the same class, so that the calculated class member can be used just like an explicitly defined class member would. For example imagine a struct called creature that has the properties/members creature.numberofhands, creature.fingersperhand and finally the property creature.totalfingers that automatically gets calculated from the above members.
Heres an example of the closest I got to what I wanted to achieve:
#include <iostream>
typedef struct creature {
int numberofhands;
int fingersperhand;
int totalfingers();
} creature;
int creature::totalfingers()
{
return numberofhands * fingersperhand;
};
int main()
{
creature human;
human.numberofhands = 2;
human.fingersperhand = 5;
printf("%d",human.totalfingers());
return(0);
}
What's really annoying me about this, is that I have to treat the calculated one DIFFERENTLY from the explicitly defined ones, i.e. I have to put "()" after it.
How can I change the code, so I can use: human.totalfingers without ever explicitly defining it?
The simplest option would be to use public member functions and make the actual properties hidden.
Something like this:
class Creature {
public:
Creature(int numhands, int fingersperhand) // constructor
: m_numhands{numhands}, m_fingersperhand{fingersperhand}
{ }
int fingersPerHand() const { return m_fingersperhand; }
int numberOfHands() const { return m_numhands; }
int totalFingers() const { return numberOfHands() * fingersPerHand(); }
private:
const int m_numhands;
const int m_fingersperhand;
};
The private member variables are an implementation detail. Users of the class just use the three public member functions to get the different number of fingers after construction and don't need to care that two of them are returning constant stored numbers and the third returns a calculated value - that's irrelevant to users.
An example of use:
#include <iostream>
int main()
{
Creature human{2, 5};
std::cout << "A human has "
<< human.totalFingers() << " fingers. "
<< human.fingersPerHand() << " on each of their "
<< human.numberOfHands() << " hands.\n";
return 0;
}
If - as per your comment - you don't want to use a constructor (although that's the safest way to ensure you don't forget to initialize a member), you can modify the class like this:
class CreatureV2 {
public:
int fingersPerHand() const { return m_fingersperhand; }
int numberOfHands() const { return m_numhands; }
int totalFingers() const { return numberOfHands() * fingersPerHand(); }
void setFingersPerHand(int num) { m_fingersperhand = num; }
void setNumberOfHands(int num) { m_numhands = num; }
private:
// Note: these are no longer `const` and I've given them default
// values matching a human, so if you do nothing you'll get
// human hands.
int m_numhands = 2;
int m_fingersperhand = 5;
};
Example of use of the modified class:
#include <iostream>
int main()
{
CreatureV2 human;
std::cout << "A human has "
<< human.totalFingers() << " fingers. "
<< human.fingersPerHand() << " on each of their "
<< human.numberOfHands() << " hands.\n";
CreatureV2 monster;
monster.setFingersPerHand(7);
monster.setNumberOfHands(5);
std::cout << "A monster has "
<< monster.totalFingers() << " fingers. "
<< monster.fingersPerHand() << " on each of their "
<< monster.numberOfHands() << " hands.\n";
CreatureV2 freak;
freak.setFingersPerHand(9);
// Note: I forgot to specify the number of hands, so a freak get
// the default 2.
std::cout << "A freak has "
<< freak.totalFingers() << " fingers. "
<< freak.fingersPerHand() << " on each of their "
<< freak.numberOfHands() << " hands.\n";
return 0;
}
Note: all of the above assumes you are using a modern C++14 compiler.
What you have described is one of the reasons why encapsulation and "member variables should be private" is the recommended way of doing things in C++.
If every variable is accessed through a function, then everything is consistent, and refactoring from a member variable to a computation is possible.
Some languages, like C# or D, have the concept of "properties", which provide a way around the issue, but C++ does not have such a construct.
For fun, the proxy way to avoid extra parenthesis, (but with some extra costs):
class RefMul
{
public:
RefMul(int& a, int& b) : a(a), b(b) {}
operator int() const { return a * b; }
private:
int& a;
int& b;
};
struct creature {
int numberofhands;
int fingersperhand;
RefMul totalfingers{numberofhands, fingersperhand};
};
Demo
Note: to use RefMul with printf, you have to cast to int:
printf("%d", int(human.totalfingers));
That cast would not be required if you use c++ way to print:
std::cout << human.totalfingers;
If you're after consistency, you can make your changes the other way around. Replace the two member variables with constant methods which simply return copies of the member variables. That way, the way you access data is consistent and you don't have to worry about some code changing the values of the member variables when it shouldn't.
Others have provided very good answers. If you are looking for consistency, probably the easiest way is to make use of member functions (as #Jesper Juhl has answered).
On the other hand, if you strictly want to use class members that are calculated automatically from other members, you can use properties. Properties (as are defined in C# and Groovy) are not a standard feature of C++ but there are ways to implement them in C++. This SO question has a very good overview of the ways that properties can be defined and used in C++. My favorite way of defining properties is taking advantage of Microsoft-specific extension for properties in Visual C++ (obviously, this approach is specific to Microsoft Visual C++). A documentation of properties in Visual C++ can be found in MSDN. Using properties in Visual C++, your code can be modified to:
struct creature {
int numberofhands; // use of public member variables are generally discouraged
int fingersperhand;
__declspec(property(get = get_totalfingers)) // Microsoft-specific
int totalfingers;
private:
int fingers;
int get_totalfingers()
{
return numberofhands * fingersperhand; // This is where the automatic calculation takes place.
}
};
This class can be used like this:
#include <iostream>
int main()
{
creature martian;
martian.numberofhands = 2;
martian.fingersperhand = 4; // Marvin the Martian had 4!
// This line will print 8
std::cout << "Total fingers: " << martian.totalfingers << std::endl;
return 0;
}
As I said earlier, properties are not a standard feature of C++ but there are ways to get them in C++ which either rely on smart tricks or using compiler-specific features. IMHO, using simple functions (as #Jesper Juhl described) is a better alternative.
This question already has answers here:
Correct way of initializing a struct in a class constructor
(5 answers)
Closed 8 years ago.
So I read about Plain Old Data classes (POD) , and decided to make my structs POD to hold data. For example, I have
struct MyClass {
int ID;
int age;
double height;
char[8] Name;
};
Obviously, to assign values to the struct, I can do this:
MyClass.ID = 1;
MyClass.age = 20;
...
But is there anyway to assign raw data, WITHOUT knowing the name of each field?
For example, My program retrieves field value for each column,, and I want to assign the value to the struct, given that i don't know the name of the fields..
MyClass c;
while (MoreColumns()) {
doSomething( c , GetNextColumn() ); //GetNextColumn() returns some value of POD types
}
I'm assuming there's way to do this using memcpy, or something std::copy,, but Not sure how to start..
Sorry if the question is a bit unclear.
You can use aggregate initialization:
MyClass c1 = { 1, 20, 6.0, "Bob" };
MyClass c2;
c2 = MyClass{ 2, 22, 5.5, "Alice" };
There is no general way to loop over the members of a struct or class. There are some tricks to add data and functions to emulate that sort of thing, but they all require additional setup work beyond just declaring the type.
Since MyClass is an aggregate, you can use a brace-initializer to initialize all fields in one call, without naming any of them:
MyClass m {
1,
2,
42.0,
{ "Joseph" }
};
However, given your description, maybe a POD is not a good idea, and you might want to design a class with accessors to set internal fields based on (for example) index columns.
Maybe boost::fusion can help you with what you want to archive.
You can use the adapt macro to iterate over a struct.
From the example of boost:
struct MyClass
{
int ID;
int age;
double height;
};
BOOST_FUSION_ADAPT_STRUCT(
MyClass,
(int, ID)
(int, age)
(double, height)
)
void fillData(int& i)
{
i = 0;
}
void fillData(double& d)
{
d = 99;
}
struct MoreColumns
{
template<typename T>
void operator()(T& t) const
{
fillData(t);
}
};
int main()
{
struct MyClass m = { 33, 5, 2.0 };
std::cout << m.ID << std::endl;
std::cout << m.age << std::endl;
std::cout << m.height << std::endl;
MoreColumns c;
boost::fusion::for_each(m, c);
std::cout << m.ID << std::endl;
std::cout << m.age << std::endl;
std::cout << m.height << std::endl;
}
What you are trying to achieve usually leads to hard-to-read or even unreadable code. However, assuming that you have a genuinely good reason to try to assign (as opposed to initialize) raw data to a field without knowing its name, you could use reinterpret_cast as below (Link here). I don't recommend it, but just want to point out that you have the option.
#include <cstdio>
#include <cstring>
struct Target { // This is your "target"
char foo[8];
};
struct Trap {
// The "trap" which lets you manipulate your target
// without addressing its internals directly.
// Assuming here that an unsigned occupies 4 bytes (not always holds)
unsigned i1, i2;
};
int main() {
Target t;
strcpy(t.foo, "AAAAAAA");
// Ask the compiler to "reinterpet" Target* as Trap*
Trap* tr = reinterpret_cast<Trap*>(&t);
fprintf(stdout, "Before: %s\n", t.foo);
printf("%x %x\n", tr->i1, tr->i2);
// Now manipulate as you please
// Note the byte ordering issue in i2.
// on another architecture, you might have to use 0x42424200
tr->i1 = 0x42424242;
tr->i2 = 0x00424242;
printf("After: %s\n", t.foo);
return 0;
}
This is just a quick example I came up with, you can figure out how to make it "neater". Note that in the above, you could also access target iteratively, by using an array in "Trap" instead of i1, i2 as I have done above.
Let me reiterate, I don't recommend this style, but if you absolutely must do it, this is an option you could explore.
Is there a (more or less at least) standard int class for c++?
If not so, is it planned for say C++13 and if not so, is there any special reasons?
OOP design would benefit from it I guess, like for example it would be nice to have an assignment operator in a custom class that returns an int:
int i=myclass;
and not
int i=myclass.getInt();
OK, there are a lot of examples where it could be useful, why doesn't it exist (if it doesn't)?
It is for dead reckoning and other lag-compensating schemes and treating those values as 'normal' variables will be nice, hopefully anyway!.
it would be nice to have an assignment operator in a custom class that returns an int
You can do that with a conversion operator:
class myclass {
int i;
public:
myclass() : i(42) {}
// Allows implicit conversion to "int".
operator int() {return i;}
};
myclass m;
int i = m;
You should usually avoid this, as the extra implicit conversions can introduce ambiguities, or hide category errors that would otherwise be caught by the type system. In C++11, you can prevent implicit conversion by declaring the operator explicit; then the class can be used to initialise the target type, but won't be converted implicitly:
int i(m); // OK, explicit conversion
i = m; // Error, implicit conversion
If you want to allow your class to implicitly convert to int, you can use an implicit conversion operator (operator int()), but generally speaking implicit conversions cause more problems and debugging than they solve in ease of use.
If your class models an int, then the conversion operator solution presented by other answers is fine, I guess. However, what does your myclass model?
What does it mean to get an integer out of it?
That's what you should be thinking about, and then you should come to the conclusion that it's most likely meaningless to get an integer without any information what it represents.
Take std::vector<T>::size() as an example. It returns an integer. Should std::vector<T> be convertible to an integer for that reason? I don't think so. Should the method be called getInt()? Again, I don't think so. What do you expect from a method called getInt()? From the name alone, you learn nothing about what it returns. Also, it's not the only method that returns an integer, there's capacity() too.
Implement operator int () for your class
This can be realized by the cast operator. E.g:
class MyClass {
private:
int someint;
public:
operator const int() {
return this->someint;
}
}
No there isn't any standard int class. For things such as BigDecimal you can look at Is there a C++ equivalent to Java's BigDecimal?
As for int, if you really need it, you can create your own. I have never come across an instance where I needed an Integer class.
No, and there won't be any. What you want to do can be done with conversion operator:
#include <iostream>
struct foo {
int x;
foo(int x) : x(x) {}
operator int() { return x; }
};
int main() {
foo x(42);
int y(x);
std::cout << y;
}
No, and there probably won't be.
int i=myclass;
This is covered by conversion operators:
struct MyClass {
operator int() {
return v;
}
int v;
} myclass = {2};
int i = myclass; // i = 2
Not everything has to be 'object oriented'. C++ offers other options.
There are obvious reasons to have a class for int, because int by itself does not allow for the absence of any value. Take for instance a JSON message. It can contain the definition for an object named “foo”, and an integer named “bar”, for example:
{"foo": {"bar": 0}}
Which has the meaning that “bar" is equal to 0 (zero), but if you omit “bar”, like this:
{"foo": {}}
Now it takes on the meaning that “bar” is non-existent, which is a completely different meaning and cannot be represented by int alone. In the old days, if this situation arose, some programmers would use a separate flag, or use a specific integer value to signify that the value was not supplied, or undefined, or non-existent. But whatever you call it, a better way is to have a class for integer which defines the functionality and makes it reusable and consistent.
Another case would be a database table that has an integer column added some time after it’s creation. Records that were added prior to when the new column was added will return null, meaning no value present, and records added after the column’s creation would return a value. You may need to take a different action for null value vs. 0 (zero).
So here's the beginnings of what a class for int or string might look like. But before we get to the code, let's look at the usage as that is why you would create the class in the first place, to make your life easier in the long run.
int main(int argc, char **argv) {
xString name;
xInt age;
std::cout<< "before assignment:" << std::endl;
std::cout<< "name is " << name << std::endl;
std::cout<< "age is " << age << std::endl;
// some data collection/transfer occurs
age = 32;
name = "john";
// data validation
if (name.isNull()) {
throw std::runtime_error("name was not supplied");
}
if (age.isNull()) {
throw std::runtime_error("age was not supplied");
}
// data output
std::cout<< std::endl;
std::cout<< "after assignment:" << std::endl;
std::cout<< "name is " << name << std::endl;
std::cout<< "age is " << age << std::endl;
return 0;
}
Here is the sample output from the program:
before assignment:
name is null
age is null
after assignment:
name is john
age is 32
Note that when the instance of the xInt class has not been assigned a value, the << operator automatically prints "null" instead of zero, and the same applies to xString for name. What you do here is totally up to you. For instance, you might decide to print nothing instead of printing “null”. Also, for the sake of brevity, I've hard coded the assignments. In the real world, you would be gathering/parsing data from a file or client connection, where that process would either set (or not set) the data values according to what is found in the input data. And of course, this program won't actually ever throw the runtime exceptions, but I put them there to give you a flavor of how you might throw the errors. So, one might say, well, why don't you just throw the exception in your data collection process? Well, the answer to that is, with the eXtended class variables (xInt & xString), we can write a generic, reusable, data gathering process and then just examine the data that is returned in our business logic where we can then throw appropriate errors based on what we find.
Ok, so here's the class code to go with the above main method:
#include <iostream>
#include <string>
class xInt {
private:
int _value=0;
bool _isNull=true;
public:
xInt(){}
xInt(int value) {
_value=value;
_isNull=false;
}
bool isNull(){return _isNull;}
int value() {return _value;}
void unset() {
_value=0;
_isNull=true;
}
friend std::ostream& operator<<(std::ostream& os, const xInt& i) {
if (i._isNull) {
os << "null";
} else {
os << i._value;
}
return os;
}
xInt& operator=(int value) {
_value=value;
_isNull=false;
return *this;
}
operator const int() {
return _value;
}
};
class xString {
private:
std::string _value;
bool _isNull=true;
public:
xString(){}
xString(int value) {
_value=value;
_isNull=false;
}
bool isNull() {return _isNull;}
std::string value() {return _value;}
void unset() {
_value.clear();
_isNull=true;
}
friend std::ostream& operator<<(std::ostream& os, const xString& str) {
if (str._isNull) {
os << "null";
} else {
os << str._value;
}
return os;
}
xString& operator<<(std::ostream& os) {
os << _value;
return *this;
}
xString& operator=(std::string value) {
_value.assign(value);
_isNull=false;
return *this;
}
operator const std::string() {
return _value;
}
};
Some might say, wow, that's pretty ugly compared to just saying int or string, and yes, I agree that it's pretty wordy, but remember, you only write the base class once, and then from then on, your code that you're reading and writing every day would look more like the main method that we first looked at, and that is very concise and to the point, agreed? Next you'll want to learn how to build shared libraries so you can put all these generic classes and functionality into a re-usable .dll or .so so that you're only compiling the business logic, not the entire universe. :)
There's no reason to have one, and so there won't be any.
Your cast operator should realize this
An example
class MyClass {
private:
int someint;
public:
operator const int() {
return this->someint;
}
}
Edit:
So this question was misinterpreted to such a ludicrous degree that it has no point anymore. I don't know how, since the question that I actually asked was whether my specific implementation of this—yes, known to be pointless, yes, not remotely resembling idiomatic C++—macro was as good as it could be, and whether it necessarily had to use auto, or if there was a suitable workaround instead. It was not supposed to generate this much attention, and certainly not a misunderstanding of this magnitude. It's pointless to ask respondents to edit their answers, I don't want anybody to lose reputation over this, and there's some good information floating around in here for potential future viewers, so I'm going to arbitrarily pick one of the lower-voted answers to evenly distribute the reputation involved. Move along, nothing to see here.
I saw this question and decided it might be fun to write a with statement in C++. The auto keyword makes this really easy, but is there a better way to do it, perhaps without using auto? I've elided certain bits of the code for brevity.
template<class T>
struct with_helper {
with_helper(T& v) : value(v), alive(true) {}
T* operator->() { return &value; }
T& operator*() { return value; }
T& value;
bool alive;
};
template<class T> struct with_helper<const T> { ... };
template<class T> with_helper<T> make_with_helper(T& value) { ... }
template<class T> with_helper<const T> make_with_helper(const T& value) { ... }
#define with(value) \
for (auto o = make_with_helper(value); o.alive; o.alive = false)
Here's an (updated) usage example with a more typical case that shows the use of with as it is found in other languages.
int main(int argc, char** argv) {
Object object;
with (object) {
o->member = 0;
o->method(1);
o->method(2);
o->method(3);
}
with (object.get_property("foo").perform_task(1, 2, 3).result()) {
std::cout
<< (*o)[0] << '\n'
<< (*o)[1] << '\n'
<< (*o)[2] << '\n';
}
return 0;
}
I chose o because it's an uncommon identifier, and its form gives the impression of a "generic thing". If you've got an idea for a better identifier or a more usable syntax altogether, then please do suggest it.
If you use auto, why use macros at all?
int main()
{
std::vector<int> vector_with_uncommonly_long_identifier;
{
auto& o = vector_with_uncommonly_long_identifier;
o.push_back(1);
o.push_back(2);
o.push_back(3);
}
const std::vector<int> constant_duplicate_of_vector_with_uncommonly_long_identifier
(vector_with_uncommonly_long_identifier);
{
const auto& o = constant_duplicate_of_vector_with_uncommonly_long_identifier;
std::cout
<< o[0] << '\n'
<< o[1] << '\n'
<< o[2] << '\n';
}
{
auto o = constant_duplicate_of_vector_with_uncommonly_long_identifier.size();
std::cout << o <<'\n';
}
}
EDIT: Without auto, just use typedef and references.
int main()
{
typedef std::vector<int> Vec;
Vec vector_with_uncommonly_long_identifier;
{
Vec& o = vector_with_uncommonly_long_identifier;
o.push_back(1);
o.push_back(2);
o.push_back(3);
}
}
?? attempted vb syntax into C++
with says do all the things in the following block by default referencing the object I've said to do it with right? Executes a series of statements making repeated reference to a single object or structure.
with(a)
.do
.domore
.doitall
so how is the example giving you the same syntax?
to me examples of why to use a with where multiple de referencess
so rather than
book.sheet.table.col(a).row(2).setColour
book.sheet.table.col(a).row(2).setFont
book.sheet.table.col(a).row(2).setText
book.sheet.table.col(a).row(2).setBorder
you have
with( book.sheet.table.col(a).row(2) )
.setColour
.setFont
.setText
.setBorder
seems just as easy, and more common syntax in C++ to
cell& c = book.sheet.table.col(a).row(2);
c.setColour
c.setFont
c.setText
c.setBorder
For C++0x (which you're assuming):
int main() {
std::vector<int> vector_with_uncommonly_long_identifier;
{
auto& o = vector_with_uncommonly_long_identifier;
o.push_back(1);
o.push_back(2);
o.push_back(3);
}
}
Why not just use a good lambda?
auto func = [&](std::vector<int>& o) {
};
func(vector_with_a_truly_ridiculously_long_identifier);
The simple fact is that if your identifiers are so long, that you can't type them out every time, use a reference, function, pointer, etc to solve this problem, or better, refactor the name. Statements like this (e.g. using() in C#) have additional side effects (deterministic cleanup, in my example). Your statement in C++ has no notable actual benefits, since it doesn't actually invoke any additional behaviour against just writing the code out.