只是一個q & d黑客,但它應該提供一些提示。
不知何故,我知道,一個甚至可以擺脫那個醜陋的「虛擬」參數,但我沒有看到,現在
編輯七月六日
我做了ansatz使用起來更加無縫。 概念「身份」,有什麼問題揭幕戰顯然瞄準的編譯時間測試,將需要
//T t1, t2;
(t1 == t2) == (&t1 == &t2);
編譯時的測試,這是國際海事組織不可能的。 因此,我介紹了功能列表的概念,以便於手動指定這些功能。
#include <iostream>
#include <typeinfo>
#include <type_traits>
#ifdef __GNUG__
#include <cxxabi.h>
auto type_str = [](const std::type_info& ti) {
int stat;
return abi::__cxa_demangle(ti.name(), 0, 0, &stat);
};
#else
#warning untested
auto type_str = [](const std::type_info& ti) {
return ti.name();
};
#endif
typedef int Feature;
const Feature HAS_IDENTITY = 1;
const Feature HAS_FOOBAR = 2;
const Feature HAS_NO_IDENTITY = -HAS_IDENTITY;
const Feature HAS_NO_FOOBAR = -HAS_FOOBAR;
const Feature _TERM_ = 0;
template<typename T, Feature F>
struct has_feature : std::false_type {};
template<int N , int M>
struct is_greater {
constexpr static bool value = N > M;
};
namespace detail {
template<class T, Feature... Fs> struct List {}; // primary template
template<class T, Feature F>
struct List<T,F> {};
template<class T, Feature F, Feature... Fs>
struct List<T,F,Fs...>
: virtual public
std::conditional<
has_feature<T,F>::value,
List<T, F>,
List<T, -F>
>::type,
virtual public
std::conditional<
is_greater<sizeof...(Fs),0>::value,
List<T, Fs...>,
List<T, _TERM_>
> ::type {};
template<class T> struct List<T, _TERM_> {};
template<class T>
struct List<T,HAS_NO_FOOBAR> {
virtual std::string hello() const /* = 0;*/ {
return std::string("\"What the foo is FOOBAR?\", askes ") + type_str(typeid(T));
}
};
template<class T>
struct List<T,HAS_FOOBAR> {
virtual std::string hello() const /* = 0;*/ {
return std::string("\"For sure I'm FOOBAR\", says ") + type_str(typeid(T));
}
};
template<class T>
struct List<T,HAS_NO_IDENTITY> {
virtual int index(const T& what) const /* = 0;*/ {
return 137;
}
};
template<class T>
struct List<T,HAS_IDENTITY> {
virtual int index(const T& what) const /* = 0;*/ {
return 42;
}
};
template<typename T>
using Feature_Aware_List = List<T,HAS_IDENTITY,HAS_FOOBAR, /* all Features incuding*/_TERM_>;
} //namespace detail
template<typename T>
using List = detail::Feature_Aware_List<T>;
struct Gadget {
bool operator== (const Gadget& rhs) const {
return this == &rhs;
}
};
struct Gimmick {
bool operator== (const Gimmick& rhs) const {
return this == &rhs;
}
};
template<Feature F>
struct FeatureList {};
template<>
struct FeatureList<HAS_IDENTITY>
: public Gadget,
public Gimmick
/**/
{};
#include <valarray>
template<>
struct FeatureList<HAS_FOOBAR>
: public std::valarray<float>
/**/
{};
template<class T>
struct has_feature<T, HAS_IDENTITY>
: public std::conditional<
std::is_base_of<T, FeatureList<HAS_IDENTITY>>::value,
std::true_type,
std::false_type
>::type {};
template<class T>
struct has_feature<T, HAS_FOOBAR>
: public std::conditional<
std::is_base_of<T, FeatureList<HAS_FOOBAR>>::value,
std::true_type,
std::false_type
>::type {};
int main() {
List<Gadget> l1 ;
List<std::valarray<float>> l2;
std::cout << l1.hello() << " #" << l1.index(Gadget()) << std::endl;
std::cout << l2.hello() << " #" << l2.index(std::valarray<float>()) << std::endl;
}
輸出:
"What the foo is FOOBAR?", askes Gadget #42
"For sure I'm FOOBAR", says std::valarray<float> #137
它應該是自我解釋,沒有特定的 「列表」 的功能實現,這是模擬只
所以*身份證*的概念,是指可以使用'比擬的任何類型==操作符'?我不明白你怎麼能'countOccurrences'爲一種不平等的類型,但我想這與回答你的問題無關。 – Praetorian
@Praetorian http://en.wikipedia.org/wiki/Identity_%28object-oriented_programming%29字符串沒有身份,如果我給你在內存中不同位置的兩個字符串,他們不是獨特的,'== '可以明確地定義。具有**身份的類型**使得可能在比特上完全相同的事物明顯不同,考慮例如姓名和年齡表中的記錄,「身份證」或「身份證」可以將具有相同姓名的兩個人分開同樣的年齡。在GUI程序中,我可以打開兩個相同的框架,它們具有標識(並且明顯不同),這就是爲什麼sizeof(struct {})== 1的原因。 –
所以@Praetorian在這種情況下,如果列表存儲的是具有身份的東西,例如「countOccurrences」和「find」都是愚蠢的,「contains」和「index」就非常合適。當「性能」這樣的現實世界發揮作用時,這個概念變得有點模糊:P一般來說:如果使用引用或指針是身份,那麼任何通過值傳遞的內容(使用C++)都缺乏身份。 –