c++方法作为模板参数
c++ method as template argument
我正试图用自定义哈希和自定义等式来专门化类X的std::unordered_map。问题是等式和散列函数不仅取决于类X的对象,还取决于另一类Y的另一个(固定)对象中的数据
#include <unordered_map>
using namespace std;
struct Y {
bool b;
struct X {
size_t i;
};
size_t hash(const X &x) {
return x.i + b;
}
unordered_map<X, int, hash> mymap;
};
问题是,模板专用化中的函数哈希是一种方法,编译器会抱怨("在没有对象参数的情况下调用非静态成员函数")。我想要的是y.mymap使用y.hash()。有办法做到这一点吗?
请注意,在实际代码中,Y也是一个模板,以备不时之需。
谢谢!
编辑:为了澄清,我的代码中没有布尔值b,而是有一个向量,其中包含比较X类型对象所需的数据。一些数据是在创建X时添加的,所以向量不是恒定的,但给定X的数据在添加后不会改变,所以给定X的哈希永远不会改变(所以从某种意义上说,它只取决于哈希所需的X)。我使用这种方法的主要原因是为了节省内存,因为这些数据很多,而且通常是共享的。
您可以使用function<size_t(X const&)>
,例如bind
,但由于在这种情况下不需要类型擦除,因此这里有一个更简单的解决方案:
struct Y {
bool b;
struct X {
size_t i;
bool operator==(X x) const {return i == x.i;}
};
size_t hash(const X &x) {
return x.i + b;
}
struct Hasher {
Y* this_;
template <typename T>
auto operator()(T&& t) const
-> decltype(this_->hash(std::forward<T>(t))) {
return this_->hash(std::forward<T>(t));
}
};
unordered_map<X, int, Hasher> mymap;
Y() : b(false),
mymap(0, {this}) {}
};
正如@dyp在评论中提到的,您必须小心使用特殊的成员函数,因为我们将this
隐式存储在mymap
中,即编译器生成的定义将复制this_
指针。移动构造函数的一个示例实现可以是
Y(Y&& y) : b(y.b), mymap(std::make_move_iterator(std::begin(y.mymap)),
std::make_move_iterator(std::end (y.mymap)), 0, {this}) {}
不幸的是,您想要做的是不合法的。见17.6.3.5表26:
h(k)
返回的值应仅取决于参数k。
很明显,不允许哈希依赖于Y
和X
的成员。
编辑:如果你想让b
在你的Y
类中成为常量,有一个解决方案(我还没有编译这个,如果有机会的话我会编译的):
struct Y
{
explicit Y(bool config) : b(config), hash_(config), mymap(0, hash_) { }
const bool b;
struct X
{
size_t i;
};
struct Hash
{
explicit Hash(bool b) : b_(b) { }
size_t operator()(const X& x) const
{
return x.i + b_;
}
private:
bool b_;
};
Hash hash_;
unordered_map<X, int, Hash> mymap;
};
相关文章:
- 使用在用于SFINAE的void_t中具有参数的方法
- 如何制作一个将函数作为参数的类方法
- c++方法参数只能在linux的发布模式下自行更改
- 使用用户定义的参数调用future/async并调用类方法
- 将成员函数指针作为参数传递给模板方法
- 在 cpp 文件中隐藏采用模板参数引用的方法
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 具有字符串化的可变参数宏的现代/通用方法
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- 如何在方法中传递结构参数
- 如何将类成员方法的参数列表自动填充写入可变参数?
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- C++方法是否可以根据传递给构造函数的参数具有不同的返回类型?
- C++接口继承不同的参数方法
- C++ 模板:重载时找不到基类类型参数方法
- 如何使用迭代器作为参数方法?
- 具有不同亚型的参数方法
- 如何以相同的方法在子类中超载的相同方法来实现工作变量参数方法
- 如何将 C 中声明的可选参数方法转换为 c++
- 如果模板化"ResourceCache"需要不同的创建参数/方法,它们如何加载/创建 T 类型的资源?