2016-04-11 53 views
3

Farklı tamsayı türlerinde farklı miktarlarda bit vardiyaları yapan bir işlev şablonuna ihtiyacım olduğunu varsayalım. Örneğin, n girdi değeri char türünde ise, işlev n>>2 ve n<<3 numaralı hesaplarda bazı hesaplamalar yapar. short int ise, işlev n>>1 ve n<<8 kullanır. int türü için n>>11 ve n<<9 vb. Tabii ki, bahsedilen değerler sadece örneklerdir ve bunlar arasında ve int_tip boyutu arasında bir korelasyon yoktur.Özelleştirilmiş bit kaydırma değerlerine sahip bir şablon nasıl oluşturulur

template <typename Num_Type = char, int s1 = 2, int s2 = 3> void test1(Num_Type &n) 
{ 
    // this is just an example code: 
    int a = n >> s1, 
     b = n << s2; 
    // do some calculations on a and b 
} 

Yani giriş değerinin farklı türleri için bu şablonu kullanabilirsiniz: Bu sorunun

Benim önerim böyle bir şey oldu. Ama derlediğimde, vardiyalı işlemlerde tanımlanmamış davranışlarla ilgili birkaç uyarı veriyor, çünkü değer çok büyük olabilir.

Yani soru iki şekilde sorulabilir:

  1. nasıl "tanımsız davranış" uyarıları almadan bit kaydırma işlemlerini özelleştirebilirsiniz? veya 0, 1, 2, ... , 310, 1, 2, ... , 31: Belirtilen bir sayı aralığı olan intlength gibi sınırlı bir veri türüne sahip olabilir miyim? Aptalca gelebilir, biliyorum, ama bu durumda ben

    template <typename Num_Type = char, intlength s1 = 2, intlength s2 = 3> void test1(Num_Type &n) 
    

olarak şablon tanımlayabilir ve böylece derleyici kaydırma değerleri hakkında şikayetçi olmamalı.

+0

Neden uyarıları alabilirim? Yani niçin n 'yi çok büyük bir s1' veya 's2' ile değiştirmeye çalışıyorsun? – rozina

+0

@rozina Çok büyük değerlerle değiştirmeye çalışmıyorum, Amaçlanan değerlerim küçüktür, ancak vardiya miktarı int türünde olduğundan, derleyici çok büyük –

+0

görebileceğimi düşünüyor. Belki de uyarı burada yararlı değildir ve bu işlev için devre dışı bırakabilirsiniz. Ve güvende olmak için 's1' ve s2''nün çok büyük olmadığını test etmek için işlev gövdesine ekler ekleyebilirsiniz. [Clang herhangi bir uyarı üretmez ama] (http://coliru.stacked-crooked.com/a/ad90bdc4aec37f1f) – rozina

cevap

0

Şablon türü davranışını giriş türüne göre değiştirmenin sağlıklı yolu, şablon uzmanlığı kullanmaktır. Örneğin: Taşma olmadığından emin olmak için vardiyalarınızı kontrolleri ile çevrelediğinizden emin olun. Ayrıca, herhangi bir taşma olmadığından emin olmak için vardiyalarınızı çevrelediğinizden emin olun.

+0

Bu bir fark yaratmıyor –

0

Şablonlara gerek duymuyorum.

auto test(char n) { ... } 
auto test(uint16_t n) { .. } 
auto test(uint32_t n) { .. } 
+0

Bunu biliyorum. Amacım bir problemi "çözmek" değil. –

+0

Bir şey yapmak için bilmek istiyorum Ve eğer kod çok büyükse, fonksiyonun aşırı yüklenmesi –

+0

popoda bir ağrı olacaktır. O zaman sorunuzu anlamıyorum. Ne istediğini anlamadım. – bolov

1

Sen kullandığınız derleyici bağlıdır bir #pragma komutla, bu işlev için uyarıyı devre dışı bırakabilirsiniz: Tek ihtiyacınız basit aşırı yükleme olduğunu. Google'a kendin sahip olmak zorundasın.

Düzenleme: Eğer visualstudio kullandığınız söz beri uyarıyı devre dışı bıraktıktan sonra, here is a link to disable warnings. :)

Eğer s1 ve s2Num_Type aralığında ise bir static_assert kontrol etmek ekleyebilir. Her ne kadar her şey derlenme zamanında bilindiğinden, derleyicinizin bunu kendisinin yapmaması garip gelse de.

template <typename Num_Type, int s1 = 2, int s2 = 3> void test1(Num_Type &n) 
{  
    constexpr auto max = sizeof(Num_Type) * 8; 
    static_assert(s1 < max && s2 < max, "integer overflow"); 

    // this is just an example code: 
    int a = n >> s1, 
     b = n << s2; 
} 

Live demo