see this very simple code:
struct A
{
bool operator ==(const int &t)
{
return *this == t;
}
};
void main()
{
A p;
p == 2;// this code loops for ever!!!
}
dose any one know why the code loops for ever ?!
actually the operator ==() calls itself recursively!
Many thanks
Ask yourself this.
What is *this? It's struct A.
So what is *this == t ? It is basically A::operator==() with argument t.
You are calling the same function.
Related
I am pretty surprised that this struct, which is only explicitly convertible to bool, works fine inside a if statement:
struct A
{
explicit operator bool( ) const
{
return m_i % 2 == 0;
}
int m_i;
};
int main()
{
A a{ 10 };
if ( a ) // this is considered explicit
{
bool b = a; // this is considered implicit
// and therefore does not compile
}
return 0;
}
Why is it so? What is the design reason behind it in the C++ Standard?
I personally find more explicit the second conversion than the first one. To make it even more clear, I would have expected the compiler forcing to have the following for both the cases:
int main()
{
A a{ 10 };
if ( (bool)a )
{
bool b = (bool)a;
}
return 0;
}
§6.4 Selection statements [stmt.select]
The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch;
§4 Standard conversions [conv]
Certain language constructs require that an expression be converted to
a Boolean value. An expression e appearing in such a context is said
to be contextually converted to bool and is well-formed if and only
if the declaration bool t(e); is well-formed, for some invented
temporary variable t (8.5).
So the expression of the condition in if must be contextually convertible to bool, which means that explicit conversions are allowed.
This is mode most likely done because the condition of if can only evaluate to a boolean value, so by saying if(cond) you are explicitly stating you want cond to be evaluated to a boolean value.
I have a C macro defined like this:
#define normalize(c, a) c = (a) + ((a) == 0xFFFFFFFF)
I was rewriting it in Go, and as long as I know there is no such things as C macros in Go. Therefore, I created a normal function:
func normalize(a uint32, c *uint32) {
*c = a + (a == 0xFFFFFFFF)
}
The problem is that this gives me a type mismatch error. Any ideas how to fix it?
So your C normalize macro assigns c to a if a is not equal to 0xffffffff, or to 0 otherwise. I'm not sure what kind of normalization it is, but it's not my concern now.
So given the Go function signature you provided, this would work:
func normalize(a uint32, c *uint32) {
if a != 0xffffffff {
*c = a
} else {
*c = 0
}
}
However, I'm not sure why not just return a value instead of writing it via c pointer?
func normalize(a uint32) {
if a != 0xffffffff {
return a
}
return 0
}
Side note: the same applies to your C macro. By the way, the macro evaluates a twice, this might come as a surprise if you ever pass some function with side effects as a. Any reason not to use (inline) function instead of a macro, or at least make it so that it evaluates to a new value, instead of assigning c to it?
Recently, i am reading "functional programming in swift". In the book, the author does some extension of Int to meet a protocol Smaller. In order to get a thorough understanding of the author's idea, i copy the code to my own playground, but it reports error.
protocol Smaller {
static func smaller() -> Self?
}
extension Int: Smaller {
static func smaller() -> Int? {
//reporting error: Binary operator "==" cann't be applied to type of Int.type and Int
return self == 0 ? nil : self / 2
}
}
it seems that self == 0 is not allowed in the extension. Does anybody have an idea of the reason.
I don't think you wanted to use a static function as you need a instantiated integer to work on and check if it is smaller.
So there are 2 approaches:
Remove the static from the function and then call it normally:
let aInt = 4
aInt.smaller() //will be 2
or you change the signature of the static function to accept the instance as an argument
`
protocol Smaller {
static func smaller(selfToMakeSmall: Self) -> Self?
}
extension Int: Smaller {
static func smaller(selfToMakeSmall: Int) -> Int? {
//reporting error: Binary operator "==" cann't be applied to type of Int.type and Int
return selfToMakeSmall == 0 ? nil : selfToMakeSmall / 2
}
}
let theInt = 4
Int.smaller(theInt)
`
but I think this could be also improved with Generics
I'm making my way through The Swift Programming Language book, but I'm stuck on an experiment.
I'm given this code:
enum Rank: Int {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
func simpleDescription() -> String {
switch self {
case .Ace:
return "Ace"
case .Jack:
return "Jack"
case .Queen:
return "Queen"
case .King:
return "King"
default:
return String(self.toRaw())
}
}
}
For the experiment, I have to "Write a function that compares two Rank values by comparing their raw values.
I had a go:
func rankCompare(first: String, second: String) -> String {
let firstRank = Rank.first
}
But I ended up with errors because I don't know how to pass Enum values.
Can someone help?
Enum values can be passed just like other types. The following function is part of the Rank enum and compares one Rank to another.
func compareToOther(other:Rank) -> Bool { // other is of type Rank
return self.toRaw() == other.toRaw()
}
Here is a screenshot of the quick implementation and usage.
You can pass enums by just passing the enum name:
// someRank is a Rank enum value
func myFunction (someRank: Rank) -> () {
}
And then you can just call it:
myFunction(Rank.Ace)
I am also a beginner, but this is how I worked throughout the experiment. First I added this;
func compareTwoCards(card1: Rank, card2: Rank) -> String {
if card1.toRaw() == card2.toRaw() {
return "Cards are equal"
} else {
if card1.toRaw() > card2.toRaw() {
return "Card1 is greater"
} else {
return "Card2 is greater"
}
} }
Then I created two Rank objects
let ace = Rank.Ace
let queen = Rank.Queen
Finally, I called it three different ways to test it;
compareTwoCardsTake2(ace, queen)
compareTwoCardsTake2(queen, ace)
compareTwoCardsTake2(ace, ace)
Can some one with more experience please reply if there is a better/more elegant way of performing the compare?
I solved it like this:
func rankCompare(first: Rank, second: Rank) -> String {
if(first.rawValue > second.rawValue) {
return "\(first.simpleDescription()) beats \(second.simpleDescription())."
}
else if second.rawValue > first.rawValue {
return "\(second.simpleDescription()) beats \(first.simpleDescription())."
}
else {
return "\(first.simpleDescription()) equals \(second.simpleDescription())."
}
}
let king = Rank.King
let queen = Rank.Queen
let seven = Rank.Seven
rankCompare(king, queen)
rankCompare(seven, king)
rankCompare(queen, queen)
Use .rawValue for doing the comparisons and .simpleDescription() for writing out your answer.
This code can be used to determine if two enumeration values are equal or not. .toRaw() is obsolete, so .rawValue must be used to obtain the raw value for comparison. An edited version of this function (to make a full comparison with type string information, not just "true" or "false") should be used to complete the exercise. Hint For Editing: this function is of type Bool.
func compareRanks(rankA: Rank, rankB: Rank) -> Bool {
return rankA.rawValue == rankB.rawValue
}
To see the code and contributors that made this answer possible, please see the question: Explanation of The Swift Programming Language Enumerations Experiment
class StrangeFunctor
{
public:
StrangeFunctor(int (*comp)(string, string))
{
this->comp = comp;
}
int operator()(string str1, string str2)
{
return –comp(str1, str2);
}
private:
int (*comp)(string, string);
}
I was just curious as what the above code actually did. Assuming the functor was properly initialized and given to a sorting function for comparison purpose, my hunch is that it reverses the order of the passed argument, but I'm not sure if that is correct and why the would be correct.
This functor takes in a function pointer and then flips the sign on that method's return value.
return –comp(str1, str2);
If used with sorting like you said, it would invert the order of what was being sorted, given by the original function pointer.