2010-06-18 13 views
11

Lütfen ne yapmaya çalıştığımı görün:Şablon uzmanlıklarının neden farklı ad alanlarında bulunmasına izin verilmiyor?

#include <iostream> 
namespace first 
{ 
template <class T> 
class myclass 
{ 
    T t; 
public: 
    void who_are_you() const 
    { std::cout << "first::myclass"; } 
}; 
} 
namespace second 
{ 
using first::myclass; 
template <> 
class myclass <int> 
{ 
    int i, j; 
public: 
    void who_are_you() const 
    { std::cout << "second::myclass"; } 
}; 
} 

Buna izin verilmiyor. Xzx51'in neden farklı uzmanlık alanlarında uzmanlaşamadıklarını ve mevcut çözümlerin neler olduğunu açıklayabilir misiniz? Ayrıca, C++ 0x'da sabitlenmiş bir şey mi?

Bu, örneğin std::max, std::swap, std::numeric_limits vb. uzmanlaşmamı sağlar. ::std::'e bir şey ekleyerek tanımlanmamış davranışlara başvurmadan.


@AndreyT Nasıl kullanmalıyım? İşte

// my_integer is a class 
std::numeric_limits<my_integer>::max(); // specialized std::numeric_limits for my_integer 

Bu yapılabilir mi?

+0

, standart birinden devralan yeni bir şablon gelemedi? – Cogwheel

+4

§17.4.3.1/1 uyarınca: "Bir program, standart kitaplık şablonu için şablon alanı şablonunu ad alanına yazabilir. Standart kitaplık şablonunun böyle bir uzmanlığı (tam veya kısmi), bildirimin kullanıcıya bağlı olmadığı sürece tanımsız davranışla sonuçlanır. dış bağlantıların tanımlanmış adı ve uzmanlık, orijinal şablon için standart kitaplık gereksinimlerini karşılamaması durumunda. " Yani kısıtlamalar varken, * doğru şartlar altında '' std :: 'için bu tür uzmanlıkları ekleyebilirsin. –

+0

@jerry tabut Ben bir şey ekledi tanımsız bir davranışla sonuçlanacağını düşündüm! Bu gereksinimleri nasıl karşıladığını açıklayan bir cevap verebilir misiniz? – AraK

cevap

7

C++ 2003 §17.4.3.1/1: "Bir program, herhangi bir standart kitaplık şablonu için şablon uzmanlıklarını ad alanına yazabilir. Standart bir kitaplık şablonunun böyle bir uzmanlığı (tam veya kısmi), bildirimin, kullanıcı tanımlı bir dış bağlantı adıyla ilgili olmadığı sürece ve tanımlanmadıkça, tanımlanmamış bir davranışla sonuçlanır. uzmanlık, orijinal şablon için standart kitaplık gereksinimlerini karşılar. " Bu itibarla

, bir kütüphane şablonu uzmanlaşmak izin konum, ve sürece bir kullanıcı tanımlı türüne bağlıdır ve özgün şablonun şartlara uyması kaydıyla ad std da ihtisas koydu.

Düzenlenen sorunuzdaki kod, (muhtemelen) harici bağlantıya sahip olan, kullanıcı tanımlı bir ad için bir uzmanlık gibi görünüyor, bu nedenle, bu şeylerle ilgili herhangi bir sorun yaşamamasınız.senin uzmanlık orijinal şablona gereksinimlerini karşılamak sadece gereksinimi bırakır

. Senin tipin için, bunun büyük bir kısmı muhtemelen önemsiz olacak. Açıkça görülemeyen tek bölüm, sadece numeric_limits::max() değil, tüm şablon için bir uzmanlık sağlamak zorunda olduğunuzu gösteriyor. Bunlardan

namespace std { 
template <> 
class numeric_limits<my_integer> { 
public: 

    static const bool is_specialized = true; 
    static T min() throw() { return 0; 
    static T max() throw() { return /* 2^128-1 */; } // *** 
    static const int digits = 128; 
    static const int digits10 = 38; 
    static const bool is_signed = false; 
    static const bool is_integer = true; 
    static const bool is_exact = true; 
    static const int radix = 2; 
    static T epsilon() throw() { return 0; } 
    static T round_error() throw() { return 0; } 
    static const int min_exponent = 0; 
    static const int min_exponent10 = 0; 
    static const int max_exponent = 0; 
    static const int max_exponent10 = 0; 
    static const bool has_infinity = false; 
    static const bool has_quiet_NaN = false; 
    static const bool has_signaling_NaN = false; 
    static const float_denorm_style has_denorm = denorm_absent; 
    static const bool has_denorm_loss = false; 
    static T infinity() throw() { return 0; } 
    static T quiet_NaN() throw() { return 0; } 
    static T signaling_NaN() throw() { return 0; } 
    static T denorm_min() throw() { return 0; } 
    static const bool is_iec559 = false; 
    static const bool is_bounded = true; 
    static const bool is_modulo = true; 
    static const bool traps = false; 
    static const bool tinyness_before = false; 
    static const float_round_style round_style = round_toward_zero; 
}; 
} 

epeyce FP türleri için gerçekten vardır ve gerekli değildir: Yani, siz (örneğin 128 bitlik işaretsiz tamsayı türü için ballpark olmalıdır) gibi bir şey yapmak gerekecek bir tamsayı türü için anlamlı olmak; Hala uygulanmaları gerektiğine inanıyorum. Bir alternatif olarak

+0

Cevabı sağladığınız için teşekkür ederiz. Küçük bir açıklama lütfen, dış bağlantı ile kastedilen. Kitaplığım yalnızca bir başlık ise, davranış tanımlanmamıştır? – AraK

+2

Hayır - "harici bağlantı" çoğunlukla "statik" veya anonim bir ad alanında olmadığı anlamına gelir. –

+0

Harika. Artık kristal net değil :) – AraK

-4

Neden böyle bir soru ortaya çıkıyor? Anlamadan, cevaplamaya başlamak bile zor. Uzmanlık, ana şablonu değiştirir. Ana şablondan herhangi bir şekilde "çıkarılabilir" değildir. Belli bir şekilde, üst düzey bir kavram olarak, yine de aynı şablondur (daha düşük düzeyde olsa da bağımsız bir tanesi olarak tanımlanır). Bu nedenle, belli sebeplerden dolayı, ana şablonla aynı adrestedir.

Maalesef, daha iyi bir açıklama yapamıyorum çünkü böyle bir sorunun nasıl ortaya çıkacağını anlamıyorum.

BTW, "farklı ad alanında" ile ne demek istiyorsunuz? Uzmanlığın farklı ad alanının üyesi olmasını ister misiniz? Ya da uzmanlığınızın kaynak koddaki farklı bir ad alanında tanımlanmasını istiyorsunuz, ancak yine de orijinal ad alanının bir üyesi olarak kalıyorsunuz?

3

O zorlaştırmaktadır şeyler:

Ben kaygılarınızı anlıyoruz
namespace first 
{ 
    template <class T> class TArray; 
} 

namespace second 
{ 
    using first::TArray; 

    template <class U> class TArray < Node<U> >; 
    //       ^
    // Only there do you realize it's a specialization and not another template 
} 

, sık sık aynı şey için diledi. Kesinlikle mümkün görünüyor ve ben kesinlikle mantıksal gruplama argümanını almıyorum, ancak derleyici yazarlardan daha fazla çaba gerektireceğini ve C++ doğru olarak ayrıştırmanın hali hazırda yeterince zor olduğunu kabul etmeliyim. Fikrimi sorarsan eğer

Şablonlar C++ biraz dağınık, ama o zaman birikimine dayanarak ve kullanım :) 20 yıllık gördükten sonra söylemek kolay

+0

@Matthiew M. Teşekkürler. İyi cevap. – AraK

İlgili konular