c++ - 如何在 Swift 中使用泛型实现 "C++-ish template specialization"?

标签 c++ swift templates generics partial

我意识到泛型和模板是不同的,但我想我应该扔掉 C++ 式的评论,因为熟悉模板的人会知道我想要完成什么。在下面的代码中,我尝试编写一种通用成员方法来处理一种重载变体中的字符串。在另一种变体中,该方法应该处理可以从字符串初始化的数字类型。

所以,下面,我想要一个映射,并给定特定类型的变量,在映射中查找名称并将其解析为正确的类型。不幸的是,我遇到了关于 type(of:) 缺少 init() 的问题,并且在重载解析上也遇到了问题,其中 Int 类型调用想要调用为字符串定义的方法。

代码如下:

protocol StringInitializable {
    init()
    init( _: String )
}

class Foo {
    var stringMember : String
    var intMember : Int

    var lookupMap : [String:String] = [
        "string" : "Your String",
        "int": "12"
    ]

    func extractType< ParseEntity: StringInitializable >( parameter: ParseEntity, lookupName: String ) throws -> ParseEntity? {
        var x : ParseEntity?
        x = type( of: ParseEntity ).init( lookupMap[ lookupName ] )
        return x
    }

    func extractType( parameter: String, lookupName: String ) throws -> String? {
        return lookupMap[ lookupName ]
    }

    init() {
        do {
            try extractType( parameter: stringMember, lookupName: "string" )
            try extractType( parameter: intMember, lookupName: "int")
        } catch {}
    }
}

代码有点hacky,但希望有足够的内容来传达意图。如有任何帮助,我们将不胜感激。提前致谢。

最佳答案

我的上述表述存在很多问题,但我最终得到了我想要的结果。

首先,在 StringInitialized 中,我需要以下内容:

protocol StringInitializable {
    init()
    init?(_ description: String)
}

其次,我必须通过协议(protocol)扩展来扩展 Int 和 Float,以将它们标记为“字符串可初始化”:

extension Double : StringInitializable {}
extension Int : StringInitializable {}

第三,type(of:) 并不是 C++ 中 __decltype() 之类的纯粹替代品。我需要以 type(of:) 构造一个“ParseEntity”。因此,在我重新编写的代码中,关键行看起来像这样:

    var x : ParseEntity? = type( of: ParseEntity() ).init( lookupMap[ lookupName ]! )

最终的“工作”示例如下所示:

enum ParseError : Error {
    case BadParse( errorMessage: String)
}

protocol StringInitializable {
    init()
    init?(_ description: String)
}

extension Double : StringInitializable {}
extension Int : StringInitializable {}

class Foo {
    var stringMember : String = ""
    var intMember : Int = 0

    var lookupMap : [String:String] = [
        "string" : "Your String",
        "int": "12"
    ]

    func extractType< ParseEntity: StringInitializable >( parameter: ParseEntity, lookupName: String ) throws -> ParseEntity? {
        if let lookupEntry = lookupMap[ lookupName ] {
            return type( of: ParseEntity() ).init( lookupEntry )
        }
        throw ParseError.BadParse( errorMessage: "Bad parameter: \( lookupName )" )
    }

    func extractType( parameter: String, lookupName: String ) throws -> String? {
        if let lookupEntry = lookupMap[ lookupName ] {
            return lookupEntry
        }
        throw ParseError.BadParse( errorMessage: "Bad parameter: \( lookupName )" )
    }

    init() {
        do {
             stringMember = try extractType( parameter: stringMember, lookupName: "string" )!
             intMember = try extractType( parameter: intMember, lookupName: "int")!
        } catch ParseError.BadParse( let errorMessage ) {
            print( "\( errorMessage )" )
        } catch {}
    }
}


var f = Foo()
print( "\(f.intMember)" )
print( "\(f.stringMember)" )

关于c++ - 如何在 Swift 中使用泛型实现 "C++-ish template specialization"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46587888/

相关文章:

c++ - 为什么我的代码不显示我的 TButton 数组?

c++ - 未处理的异常 : Access violation reading location

c++ - QProcess 没有启动

ios - 如何更改 UITableView 中某些单元格的文本颜色?

ios - 为什么我的嵌入式 YouTube 播放器不能自动播放?

javascript - 递归 Handlebars.js 模板。如何确定深度?

c++ - 生成 url 的唯一哈希键

ios - 获取 UIImageView 中图像的大小

python - Django:标签中的For循环显示不同的信息

c++ - C++模板元编程的归纳法是什么?