std::enable_if
kullanarak, foo
iki aşırı yüklenmeyi ayırt etmem gereken bir durum var. std::enable_if
'un kendisine verilen koşul, foo
şablon parametresinin bağımlı tipine bağlıdır.std :: enable_if'in kendisi başka bir koşula bağlı olan bir koşulla nasıl kullanılır?
std::enable_if
'u kullanarak bunu ifade etmenin en iyi yolu nedir?
Aşağıdaki test kodu şu ana kadarkilere sahibim. Test kodunda istediğim davranışa ulaşmak için std::enable_if
dışında muhtemelen daha iyi yollar olduğunu anlıyorum. Ancak, aşağıdaki, kendi kullanım durumumun std::enable_if
gerektirdiği basitleştirilmiş bir sürümüdür.
#include <type_traits>
#include <cassert>
struct bar
{
using baz = int;
};
template<class T> struct is_bar : std::false_type {};
template<> struct is_bar<bar> : std::true_type {};
template<class Bar>
struct baz_type
{
using type = typename Bar::baz;
};
template<class T>
typename std::enable_if<
std::is_integral<
typename baz_type<T>::type
>::value,
int
>::type
foo(T x)
{
return 7;
}
template<class T>
typename std::enable_if<
!is_bar<T>::value,
int
>::type
foo(T x)
{
return 13;
}
int main()
{
assert(foo(bar()) == 7);
assert(foo(0) == 13);
return 0;
}
derleyici çıkışı: foo
ilk aşırı kullanılan enable_if
iç içe tip T::baz
bağlı olduğundan
$ g++ --version ; echo ; g++ -std=c++11 repro.cpp
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
repro.cpp: In instantiation of ‘struct baz_type<int>’:
repro.cpp:29:3: required by substitution of ‘template<class T> typename std::enable_if<std::is_integral<typename baz_type<Bar>::type>::value, int>::type foo(T) [with T = int]’
repro.cpp:49:3: required from here
repro.cpp:18:33: error: ‘int’ is not a class, struct, or union type
using type = typename Bar::baz;
Bu kod derleme yapmaz. int
'un bu yuvalanmış türü olmadığı için kod geçersizdir.
Ne istediğimi ifade etmenin doğru yolu nedir?
"baz_type" bir sınıf şablonu yerine bir diğer ad şablonu yapabilir misiniz? – dyp
Bir alternatif, çeşitli 'enable_if's, ör. varsayılan şablon argümanlarını kullanarak. Birincisi 'is_bar' kontrol etmeli, ikincisi' baz_type :: type' kullanabilir. Standart, sözcüksel olarak değerlendirildiğini bildirir. –
dyp
@DanielFrey * shrug * İyimserim var. Yine de çok okunabilir olmasa da, en azından [bu cevap] 'dan sonra değil (http://stackoverflow.com/a/26533335/). – dyp