今天,在第100次使用相同的模板时,我想到了引入简单替换的想法。
而不是
QHash<int,QHash<int,QHash<int,int> > >
现在应该是:
MultiKeyHash<int,int,int,int>
(不要与QT&#39的QMultiHash类混淆)。
前三个参数是键的类型,最后一个参数是值的类型。
MultiKeyHash<TKey1,TKey2,....,TKeyN,TValue>
我目前的实现如下:
template <typename... Args>
struct MultiKeyHash;
template <typename TKey1, typename... Args>
struct MultiKeyHash<TKey1, Args...> : QHash<TKey1,MultiKeyHash<Args...> > {
typedef typename MultiKeyHash<Args...>::ValueType ValueType;
const ValueType& value(const TKey1 &key1, const Args_Without_Last&... args) const {
return operator[](key1).value(args...);
}
};
template <typename TKeyN, typename TValue>
struct MultiKeyHash<TKeyN,TValue> : QHash<TKeyN,TValue> {
typedef TValue ValueType;
};
一切都按预期工作,直到我想添加&#34;值&#34;方法。我当然不能使用&#34; Args&#34;作为第二个参数的类型(-pack)。我是否必须制作它的功能模板,或者有办法吗?
我如何定义&#34;值&#34;方法,以便能够像:
一样调用它value(key1,key2,...,keyn)
答案 0 :(得分:3)
这是MultiHashKey
的工作版本。它使用QHash
的虚拟实现进行测试。
#include <iostream>
// Dummy implementation of QHash for testing purposes.
template <typename TKey, typename TValue>
struct QHash
{
void insert(const TKey& key, const TValue& val) {this->val = val;}
const TValue& value(const TKey& key) const { return val; }
TValue val;
};
template <typename... Args> struct MultiKeyHash;
template <typename TKey, typename... Args>
struct MultiKeyHash<TKey, Args...> : QHash<TKey, MultiKeyHash<Args...>>
{
typedef TKey KeyType;
typedef typename MultiKeyHash<Args...>::ValueType ValueType;
typedef QHash<KeyType, MultiKeyHash<Args...>> QHashType;
using QHashType::insert;
using QHashType::value;
MultiKeyHash() {}
MultiKeyHash(const TKey &key, const Args&... args)
{
this->insert(key, MultiKeyHash<Args...>(args...));
}
void insert(const TKey &key, const Args&... args)
{
MultiKeyHash<Args...> val(args...);
this->insert(key, val);
}
template <typename TKey1, typename ... Args1>
const ValueType& value(const TKey1 &key1, const Args1&... args1) const
{
MultiKeyHash<Args...> const& val = this->value(key1);
return val.value(args1...);
}
};
template <typename TKey, typename TValue>
struct MultiKeyHash<TKey, TValue> : QHash<TKey, TValue>
{
typedef TKey KeyType;
typedef TValue ValueType;
typedef QHash<KeyType, ValueType> QHashType;
MultiKeyHash() {}
MultiKeyHash(const TKey &key, const TValue& val)
{
this->insert(key, val);
}
};
void test1()
{
MultiKeyHash<int, double> hash;
hash.insert(10, 200.5);
double v = hash.value(10);
std::cout << "Value: " << v << std::endl;
}
void test3()
{
MultiKeyHash<int, int, int, double> hash;
hash.insert(10, 10, 10, 20.5);
double v = hash.value(10, 10, 10);
std::cout << "Value: " << v << std::endl;
}
int main()
{
test1();
test3();
return 0;
};
运行程序的输出:
Value: 200.5 Value: 20.5
答案 1 :(得分:2)
如果你使value
成为一个可变参数模板,你可以以更糟糕的错误消息为代价完全避免这个问题,因为转换将发生在函数内而不是在调用点:
template <typename First, typename...Remainder>
const ValueType& value(First&& first, Remainder&&... rest) const {
return value(std::forward<First>(first)).value(std::forward<Remainder>(rest)...);
}