5

Farz edelim ki, çift ve kullanıcı tanımlı türler dahil olmak üzere sayı benzeri türlerde kullanılabilmesi gereken bir genel kitaplık geliştirmek istiyorum. İlkel türleri için"Genel işlev" in dönüş türünün belirlenmesi

template<class T> 
auto transmogrify(T x) 
-> ??? 
{ 
    using std::abs; 
    return abs(x)+2.0; 
} 

kullanarak beyan yapar bu fonksiyon şablonun vücut çalışması:, şu anda karşı karşıya ediyorum sorun şu kadarını biri gibi bir işlev şablonunun dönüş türü yazma bilen kalmamasıdır Çünkü bunlarla ilişkili bir ad alanı yoktur (ve dolayısıyla ADL yoktur). Ancak, kullanıcı tanımlı tipte yazarın kendi abs işlevini sağlaması durumunda uzmanlık gerektiren abs fonksiyonlarını kullanmak için dönüştürücü istiyorum. std :: abs kapsamında olmadığından (anlayabilirim kadarıyla) bu diyelim ki, iki katına, için işe yaramaz çünkü sadece

-> decltype(abs(x)+2.0) 

kullanamaz. Ancak,

, ADL'yi devre dışı bırakır. Ancak, ADL'yi devre dışı bırakmak bir seçenek değildir. Ayrıca, özel bir abs işlevi tarafından döndürülen değer T türünde değil, başka türde olabilir.

İade türü sorununun nasıl çözüleceği ile ilgili herhangi bir fikir (a) ADL'yi ve (b) belirli bir varsayılan işlevi (std :: abs gibi) özel bir abs sağlamayan türler için geri almayı sürdürürken .

+0

'#define ab std :: abs kullanarak; your_template_fn #undef ab ' –

+0

yapmak için iyi bir seçim yapıp yapmayacağından emin değil misiniz? –

+1

@ Mr.Anubis ve bu tanımla işlevinin dönüş türünü nasıl tanımlar? – ForEveR

cevap

12

Kullanım maddelerini koyabileceğiniz ayrı bir ad alanı kullanın. Bu, adlandırma kirliliği yalnızca ad alanı için geçerli olduğundan ad alanı kirliliğini önler. Benzersiz bir şeyi adlandırmanızı tavsiye ederim, bu yüzden yanlışlıkla onu yaymayın.

namespace transmog_detail 
{ 
    using std::abs; 

    template<class T> 
    auto transmogrify(T x) -> decltype(abs(x) + 2.0) 
    { 
     return abs(x) + 2.0; 
    } 
} 

// Then pull it into the current namespace, as recommended by @LucDanton. 
using transmog_detail::transmogrify; 

// Or if there is a reason, you can forward. 
// template<class T> 
// auto transmogrify(T x) 
// -> decltype(transmog_detail::transmogrify(x)) 
// { 
// return transmog_detail::transmogrify(x); 
// } 
+0

Çok akıllı! Adsız ad alanları bu temizleyiciyi oluşturabilir veya oluşturmayabilir. Emin değil. –

+0

Tabii ki! :) Teşekkürler, Dave! – sellibitze

+0

@MooingDuck: Olabilir veya olmayabilir. Adlandırılmamış başka bir ad alanı kullanırsanız, bunlar da istenmeyebilecek bir kullanım maddesine sahip olurlar. –

-6

Yukarıdaki yanıtlar iyidir, ancak düşünebildiğim en basit yol, typeinfo başlığını kullanmaktır. Nesnelerin türlerini ve yapıcılarını belirlemek için özel olarak tasarlanmıştır.

buraya bakın: http://www.cplusplus.com/reference/std/typeinfo/type_info/

+4

-1 hiç yararlı değil - type_info çalışma zamanı tanımlamasıyla ilgilidir, oysa beyanın statik olarak belirlenmiş bir tür olması gerekir. –