2017-02-06 13 views
4

C++ 11では、参照型/ rvalueセマンティクスとcv修飾子を削除して、値型にジェネリック型を壊すことができます。C + 11のようなタイプの腐敗の腐食

decay<int>::type // type is `int` 
decay<const int&>::type // type is `int` 
decay<int&&>::type // type is `int` 

参照修飾子、寿命とmut修飾子を取り除きルーストに同じことを達成するための公知の機構は、ありますか?例えば:

decay<u32>::type <--- type is `u32` 
decay<&u32>::type <--- type is `u32` 
decay<&mut u32>::type <--- type is `u32` 
decay<&static u32>::type <--- type is `u32` 

背景については、私はマクロで一致した関数の引数の束の値を格納するstructを生成するマクロを記述しようとしています。例えば、マクロは引数foo: i32, bar: &Vec<String>が含まれている場合があり、得られた構造体は次のようになります。

struct GeneratedStruct { 
    foo: i32, 
    bar: Vec<String>, 
} 
+1

私はRustでは、これは特性を使用するのではなく、マクロによって直接処理されると思います。 Rustマクロはテキストではなく抽象構文木で動作することを覚えておいてください。実際にはマクロ内の引数を解析する*ことができます。 –

+0

Derefは&TをTに変えることができますが、私が間違っていなければ、Tがそれ自身ではないことを知る方法はありません。 @MatthieuM。 –

+0

マクロが助けてくれるとは思わない。 'タイプI32Ref =& '静的なi32; ...; decay!(I32Ref) 'は' i32'を生成するはずですが、これが語彙レベルで知られている方法はありません。 – kennytm

答えて

5

コメントでMatthieu M.kennytmによって示唆されるように、あなたは形質を定義し、錆1.15のような特殊(不安定な機能を使用することができます。 0)これを達成する。

#![feature(specialization)] 

use std::any::TypeId; 

trait Decay { 
    type Type; 
} 

impl<T> Decay for T { 
    default type Type = T; 
} 

impl<'a, T> Decay for &'a T { 
    type Type = <T as Decay>::Type; 
} 

impl<'a, T> Decay for &'a mut T { 
    type Type = <T as Decay>::Type; 
} 

fn foo<T: 'static>() { 
    println!("{:?}", TypeId::of::<T>()); 
} 

fn bar<T>() where <T as Decay>::Type: 'static { 
    println!("{:?}", TypeId::of::<<T as Decay>::Type>()); 
} 

fn main() { 
    foo::<<i32 as Decay>::Type>(); 
    foo::<<&i32 as Decay>::Type>(); 
    foo::<<&mut i32 as Decay>::Type>(); 
    foo::<<&&i32 as Decay>::Type>(); 

    bar::<i32>(); 
    bar::<&i32>(); 
    bar::<&mut i32>(); 
    bar::<&&i32>(); 
} 
+0

ニース!私は専門分野が関連するタイプに適用できるかどうかはわかりませんでした。 –

+0

ニース!これは仕事です。私はむしろ私のライブラリを不安定にしないでください。私はこれを調べ続け、安定した機能だけを使ってこれを行う方法を考え出すことができるかどうかを見ていきます。 –

関連する問題