2017-10-05 8 views
0

私はジェネリックとテンプレートが違うことを認識しますが、テンプレートに精通している人が私が達成しようとしていることを知っているので、私はC++を捨てると思っていました。以下のコードでは、1つのオーバーロードバリアントで文字列を処理する1つの汎用メンバーメソッドを記述しようとしています。もう一つの変形では、このメソッドは文字列から初期化できる数値型を扱うことになっています。Swiftのジェネリックスで "C++ - ishテンプレートの特殊化"を達成するにはどうすればよいですか?

以下、私はマップを取りたいと思います。特定のタイプの変数があれば、マップ内の名前を調べ、正しいタイプに解析します。残念ながら、私はタイプ(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 {} 
    } 
} 

コードは少しハックですが、うまくいけば全体の意思を伝えるには十分あります。援助はまったく役に立ちます。前もって感謝します。

答えて

0

上記の私の処方には数多くの問題がありましたが、最終的に私が働きたいものを得ました。

まず、StringInitializableで、私は次のように必要な:

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

第二に、私は "文字列初期化可能" としてそれらをマークするプロトコル拡張を経てINTとフロートを拡張する必要がありました:

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

第3に、type of(of :)はC++の__decltype()のようなものを純粋に置き換えるものではありません。私はタイプ(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)") 
だから私の再定式化コードで、臨界線はこのような何かを見て
関連する問題