Alex
Alex

Reputation: 1581

Cannot convert value of type 'A<T>' to expected argument type 'A<_>'

I'm trying to understand what I'm doing wrong.

I created a generic class pretty much in the same way as bellow (don't pay attention to the purpose of the code, it's just to show the error)

I need to define what '+' means to two instances of the class A. Unfortunately, swift complains

Cannot convert value of type 'A' to expected argument type 'A<_>'

for

public static func +(lhs: A<T>, rhs: A<T>) -> A<T> {
        return A.foobar(lhs: lhs, rhs: rhs, operation: +);
    }

And I have no idea why....

Here's the code:

import Foundation

public struct A<T:Equatable&CustomStringConvertible> {

    public let uu:T

    public init(uu:T){
        self.uu = uu;
    }
}

extension A:Equatable {
    public static func ==(lhs: A<T>, rhs: A<T>) -> Bool {
        return lhs.uu == rhs.uu
    }

    public static func +(lhs: A<T>, rhs: A<T>) -> A<T> {
        return A.foobar(lhs: lhs, rhs: rhs, operation: +);
    }

    fileprivate static func foobar(lhs: A<T>, rhs: A<T>, operation: (T, T) -> T) -> A<T> {

        return A<T>(uu:lhs.uu)
    }
}

Can anyone help?

Edit: to avoid confusion, foobar can be replaced by:

fileprivate static func foobar(lhs: A<T>, rhs: A<T>, operation: (T, T) -> T) -> A<T> {

    return A<T>(uu:operation(lhs.uu,rhs.uu))
}

Upvotes: 1

Views: 135

Answers (1)

Martin R
Martin R

Reputation: 539975

The error message is misleading. The real problem is that there is no + operator of type (T, T) -> T) under the given restrictions.

One option might be to restrict T to conform to the Numeric protocol, which requires addition, subtraction and multiplication operators:

public struct A<T:Equatable & CustomStringConvertible & Numeric> { ... }

The standard integer and floating point types conform to this protocol.

Note also that inside extension A any reference to A without generic placeholder defaults to A<T>, so you can simplify the code to

extension A: Equatable {
    public static func ==(lhs: A, rhs: A) -> Bool {
        return lhs.uu == rhs.uu
    }

    public static func +(lhs: A, rhs: A) -> A {
        return A.foobar(lhs: lhs, rhs: rhs, operation: +);
    }

    fileprivate static func foobar(lhs: A, rhs: A, operation: (T, T) -> T) -> A {
        return A(uu: operation(lhs.uu, rhs.uu))
    }
}

Upvotes: 2

Related Questions