मेरे पास एक ऐसी स्थिति है जहां मुझे foo
का उपयोग करके दो ओवरलोडों को अलग करने की आवश्यकता है, std::enable_if
का उपयोग कर। std::enable_if
को दी गई स्थिति foo
के टेम्पलेट पैरामीटर के आश्रित प्रकार पर निर्भर करती है।एक शर्त के साथ std :: enable_if का उपयोग कैसे करें जो स्वयं किसी अन्य स्थिति पर निर्भर करता है?
std::enable_if
का उपयोग करके इसे व्यक्त करने का सबसे अच्छा तरीका क्या है?
निम्न परीक्षण कोड जो मैंने अभी तक किया है। मुझे लगता है कि परीक्षण कोड में इच्छित व्यवहार को प्राप्त करने के लिए std::enable_if
के अलावा संभवतः बेहतर तरीके हैं। हालांकि, निम्नलिखित मेरे उपयोग मामले का सरलीकृत संस्करण है जिसे स्वयं std::enable_if
की आवश्यकता है।
#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;
}
संकलक उत्पादन:
$ 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;
इस कोड संकलन नहीं है क्योंकि enable_if
foo
के पहले अधिभार में इस्तेमाल नेस्टेड प्रकार T::baz
पर निर्भर करता है। क्योंकि int
में यह नेस्टेड प्रकार नहीं है, कोड अवैध है।
मुझे जो व्यक्त करना है उसे व्यक्त करने का सही तरीका क्या है?
क्या आप क्लास टेम्पलेट के बजाय 'baz_type' उपनाम टेम्पलेट बना सकते हैं? – dyp
कई विकल्प 'enable_if' का उपयोग करना है, उदा। डिफ़ॉल्ट टेम्पलेट तर्क का उपयोग कर। पहले 'is_bar' की जांच करनी चाहिए, फिर दूसरा' baz_type :: type' का उपयोग कर सकता है। मानक जनादेश है कि उनका मूल्यांकन शब्दावली क्रम में किया जाता है। –
dyp
@DanielFrey * shrug * मेरा अपवित्र है। हालांकि मैं इसे बहुत पठनीय नहीं मानूंगा, कम से कम [इस उत्तर] के बाद नहीं (http://stackoverflow.com/a/26533335/)। – dyp