Member Operator '==' Must Have at Least One Argument of Type

Member operator '==' must have at least one argument of type

You need to make your Rectangle protocol a class. Try like this:

protocol Rectangle: class, Equatable {
var width: Double { get }
var height: Double { get }
}

class Equality: Rectangle {
internal var width: Double = 0
internal var height: Double = 0
static func ==(lhs: Equality, rhs: Equality) -> Bool {
return lhs.width == rhs.width && rhs.height == lhs.height
}
}

or simply:

protocol Rectangle: Equatable {
var width: Double { get }
var height: Double { get }
}

extension Rectangle {
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.width == rhs.width && rhs.height == lhs.height
}
}

class Equality: Rectangle {
internal var width: Double = 0
internal var height: Double = 0
}

Member operator '%' must have at least one argument of type 'ViewController’

I declared the ’operator' at file scope

No, you didn't. You defined it in the scope of the
UIViewController definition:

postfix operator %

class ViewController: UIViewController {

// ...

static postfix func % (percentage: Int) -> Double {
return (Double(percentage) / 100)
}
}

One can define operators as static member functions of a type in Swift 3,
but only if they take at least one argument of that type.

Move the declaration to the file scope to fix the problem:

postfix operator %

postfix func % (percentage: Int) -> Double {
return (Double(percentage) / 100)
}

class ViewController: UIViewController {

// ...

}

why C++ operator overloading requires having at least one parameter of class type?

  1. Is this restriction part of the language specification?

Yes, it is. Why? Well, the main reason is probably because redefining the usual operators for standard types is seen as obfuscating. Imagin overloading operator+(int,int) or operator+(int,char*). That would change the meaning of existing code!

You could argue that there are operators between standard types that are not defined, so you could safely override them, for example operator*(char*,int), but that is usually seen as rather useless.

Moreover, operator overloads must be global, (or be in the namespace of some of its members (argument dependent lookup), but with standard types there are no namespace to depend on), so interoperatibility between libraries that fancy to override them would be a nightmare.

  1. "hello" + "world": why doesn't the compiler convert the two char* "s to two strings?

Well, for one, std::operator+(const std::string&, const std::string&) is in namespace std; so it will not be found by default.

You could try calling the operator explicitly: std::operator+("hello", "world"), but alas, there are so many operator+() overloads, many of them templates, that the call is ambiguous.

So, taking all this into account, I think that a reasonable requirement is that at least one of the operators to be of a user-defined type. Think about it: the global and namespace problem is solved, ADL can be used (actually it was invented for this use) and it is impossible to redefine an operator with an existing meaning (except operator,() and operator&(), I think, but who wants to override these...).

Function must have exactly one argument

Check the reference

The overloads of operator>> and operator<< that take a std::istream&
or std::ostream& as the left hand argument are known as insertion and
extraction operators. Since they take the user-defined type as the
right argument (b in a@b), they must be implemented as non-members.

Hence, they must be non-member functions, and take exactly two arguments when they are meant to be stream operators.

If you are developing your own stream class, you can overload operator<< with a single argument as a member function. In this case, the implementation would look something like this:

template<class T>
TOutputFile &operator<<(const T& a) {
// do what needs to be done
return *this; // note that `*this` is the TOutputFile object as the lefthand side of <<
}

operator must take exactly one argument

The problem is that you define it inside the class, which

a) means the second argument is implicit (this) and

b) it will not do what you want it do, namely extend std::ostream.

You have to define it as a free function:

class A { /* ... */ };
std::ostream& operator<<(std::ostream&, const A& a);

How to make a custom function with + operator in Swift

As explained by @MartinR in the comments, you need to put this function at the top level (NOT inside a class).

import Foundation

// Will compile fine from here as is
func + <T>(el: T, arr: [T]) -> [T] {
var ret = arr
ret.insert(el, at: 0)
return ret
}

class TableGenerator {
// will require at least one argument of the function to be of `TableGenerator` type
}

What causes C++ compiler error: must have argument of class or enumerated type?

What you're doing wrong here on the language level is overloading operators for pointers. At least one argument of an overloaded operator must be of a user-defined type, or a reference to one.

But you're also doing this wrong on another level. You're returning a pointer, which means you will probably need to allocate some storage dynamically in the operator. Well, who owns that storage? Who will release it?

You should just take references and return by value, something like:

template <typename T>
Point<T> operator +(Point<T> const& point, Vector<T> const& vector) {
return Point<T>(point.x + vector.x, point.y + vector.y);
}

Why must a protocol operator be implemented as a global function?

UPDATE

From the Xcode 8 beta 4 release notes:

Operators can be defined within types or extensions thereof. For example:

struct Foo: Equatable {
let value: Int
static func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.value == rhs.value
}
}

Such operators must be declared as static (or, within a class, class final), and have the same
signature as their global counterparts. As part of this change, operator requirements declared in
protocols must also be explicitly declared static:

protocol Equatable {
static func ==(lhs: Self, rhs: Self) -> Bool
}

ORIGINAL

This was discussed on the swift-evolution list recently (2016-01-31 through 2016-02-09 so far). Here's what Chris Lattner said, regarding declaring operators in a struct or class scope:

Yep, this is a generally desirable feature (at least for symmetric operators). This would also be great to get dynamic dispatch of operators within class declarations. I don’t think we have a firm proposal nailing down how name lookup works with this though.

And later (replying to Haravikk):

What are the name lookup issues? Do you mean cases where an operator for Foo == Foo exists in more than one location?


Yes. Name lookup has to have a well defined search order, which
defines shadowing and invalid multiple definition rules.

Personally I’d just stick with what we have now, i.e- treat operator implementations within a specific class/struct as being globally
defined anyway and throw an error if the same signature is declared
more than once.


We need multiple modules to be able to define instances of an
operator, we need operators in extensions, and we need retroactive
conformance to work, as with any other member.



Related Topics



Leave a reply



Submit