23

I am using Generics to add different types like Int, Double, Float, etc. I used the code below but I'm getting error "Binary operator '+' cannot be applied to two 'T' operands".

func add<T>(num1: T,num2: T) -> T {
    return num1 + num2
}
user2749248
  • 676
  • 1
  • 7
  • 15

5 Answers5

39

Swift doesn't know that the generic type T has a '+' operator. You can't use + on any type: e.g. on two view controllers + doesn't make too much sense

You can use protocol conformance to let swift know some things about your type!

I had a go in a playground and this is probably what you are looking for :)

protocol Addable {
    func +(lhs: Self, rhs: Self) -> Self
}

func add<T: Addable>(num1: T, _ num2: T) -> T {
    return num1 + num2
}

extension Int: Addable {}
extension Double: Addable {}
extension Float: Addable {}

add(3, 0.2)

Let me know if you need any of the concepts demonstrated here explained

Adam Campbell
  • 646
  • 5
  • 13
  • 1
    try add(CGFloat(2.5), Float(2.0)) – Leo Dabus Dec 07 '15 at 03:07
  • @LeoDabus Swift doesn't have a definition of + for CGFloat and Float. To solve this you can define + for CGFloat and Float. Alternatively you could change the solution slightly to cast to say, the first type. – Adam Campbell Dec 07 '15 at 03:24
  • 1
    I believe in Swift 3 the protocol must use the static keyword, e.g. : protocol Addable { static func +(lhs: Self, rhs: Self) -> Self } – Taylor H. Jun 30 '17 at 12:51
  • It's quite counter intuitive, that 1. You have to extend the type you want it to work with. 2. Your generic has to actually conform and it's not kept as a true generic...which leads to an interesting conclusion: If you ever do any sort of computation on your generics (specifying something and therefore limiting it to be able to cope with that specification), then you need to define a protocol for it, or use some protocol... – mfaani Jul 30 '17 at 18:53
23

In Swift 4 / Xcode 9+ you can take advantage of the Numeric protocol.

func add<T: Numeric>(num1: T, num2: T) -> T {
    return num1 + num2
}

print(add(num1: 3.7, num2: 44.9)) // 48.6
print(add(num1: 27, num2: 100))  // 127

Using this means you won't have to create a special protocol yourself.

This will only work in the cases where you need the functionality provided by the Numeric protocol. You may need to do something similar to @adam's answer for % and other operators, or you can leverage other protocols provided by Apple in the Xcode 9 SDK.

Paul Solt
  • 8,375
  • 5
  • 41
  • 46
6

For those who wish to use comparison such as < , > etc, simply tell Swift that your generic type adopt to comperable protocol like so: -

func genericComparison<T: Comparable>(left: LinkedList<T>, right: LinkedList<T>) -> LinkedList<T>

Mussa Charles
  • 4,014
  • 2
  • 29
  • 24
  • 1
    In fact if you put `Comparable` at class level it solves the purpose too.Like this: `final class BSTree` without the left right. – Yash Bedi Apr 28 '20 at 10:08
1

To add num1 and num2, first you need to make sure that it is of type Numeric. So, the code should look like this:

func add<T : Numeric>(num1: T,num2: T) -> T {
    return num1 + num2
}
0
protocol Addable {
    static func +(lhs: Self, rhs: Self) -> Self
}

func add<T: Addable>(num1: T, _ num2: T) -> T {
    return num1 + num2
}

extension Int: Addable {}
extension Double: Addable {}
extension Float: Addable {}

Usage :-

add(num1: 3, 5)

This Code changes of above answer i have added static keyword otherwise code will not run for latest Swift version

Dilip Tiwari
  • 1,441
  • 18
  • 31