我定义了一个类 Foo , 并希望有一个采用 std::unordered_set<Foo> 的公共(public)成员函数作为参数类型。
能够使用std::unordered_set<Foo> ,我必须专攻std::hash<Foo>在命名空间标准中。
如果我不尝试使用 std::unordered_set<Foo> 也没关系作为 Foo 中的参数类型成员函数。
但是,一旦我想使用 std::unordered_set<Foo>作为 Foo 中的参数类型成员函数,我在定义特化时遇到问题 std::hash<Foo> .
如果我在 Foo 之后做声明,Foo 上有错误声明因为std::hash<Foo>没有定义。一招std::hash<Foo>之前的定义,它也不起作用,因为现在 Foo未知。 Foo的转发声明在这种情况下不起作用。
有什么解决办法吗?
这是一个这样的类的例子
class Foo
{
public:
std::unordered_set<Foo>::iterator findClosest(std::unordered_set<Foo> const &others)
{
return std::end(others);
}
size_t hashValue() const {
return std::hash<int>()(m_Member);
}
private:
int m_Member;
};
namespace std
{
template <>
struct hash<Foo>
{
size_t operator()(Foo const & bar) const
{
return bar.hashValue();
}
};
}
使用下面的答案,这是我最终使用的代码(我需要放置一些 MY_EXPORT_MACRO 因为有 dll):
在文件 Foo.h 中
class Foo;
namespace std
{
template <>
struct MY_EXPORT_MACRO hash<Foo>
{
size_t operator()(Foo const &bar) const;
};
}
class MY_EXPORT_MACRO Foo
{
public:
Foo const *findClosest(std::unordered_set<Foo> const &others);
size_t hashValue() const
{
return std::hash<int>()(m_Member);
}
bool operator==(const platypus::Segment2D &other) const
{
return m_Member == other.m_Member;
}
private:
int m_Member;
};
在文件 Foo.cpp 中
size_t std::hash<Foo>::operator()(Foo const &bar) const
{
return bar.hashValue();
}
Foo const *Foo::findClosest(std::unordered_set<Foo> const &others)
{
Foo const *closest = nullptr;
std::unordered_set<Foo>::const_iterator closestIt =
std::min_element(std::begin(others), std::end(others), [this](Foo const &lhs, Foo const &rhs) {
return std::abs(this->m_Member - lhs.m_Member) < std::abs(this->m_Member - rhs.m_Member);
});
if (closestIt != std::end(others))
{
closest = &(*closestIt);
}
return closest;
}
最佳答案
您示例中的真正问题是您想使用 std::unordered_set<Foo>::iterator作为返回类型。这需要 unordered_set<Foo>已完全实例化,需要 Foo (和 std::hash<Foo> )成为一个完整的类(class)。但是Foo在其定义的末尾只是一个完整的类。请注意,通过引用函数参数不存在此问题,其中编译器不必完全实例化引用的类。
正如 @MrTux 最初建议的那样,您可以使用前向声明修复所有其他问题:
class Foo;
template<>
struct std::hash<Foo>;
如果您返回 Foo*相反,一切正常:
这是否适用于您的设计是另一个问题。
我应该注意到你可以有std::hash<Foo>在 Foo 之前被完全定义的定义:
class Foo;
namespace std
{
template <>
struct hash<Foo>
{
size_t operator()(Foo const & bar) const;
};
}
class Foo { /* ... */ };
size_t std::hash<Foo>::operator()(Foo const & bar) const
{
return bar.hashValue();
}
这将允许您返回例如std::unordered_set<Foo>来自 Foo 中的方法, 但它仍然没有解决 Foo 的核心问题在其自己的定义期间不完整(因此 std::unordered_set<Foo>::iterator 不可用)。
关于c++ - std::hash 专门化我自己的类并在类中使用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53334015/
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T
如何将lambda传递给hash.each,以便我可以重复使用一些代码?>h={a:'b'}>h.eachdo|key,value|end=>{:a=>"b"}>test=lambdado|key,value|puts"#{key}=#{value}"end>test.call('a','b')a=b>h.each&testArgumentError:wrongnumberofarguments(1for2)from(irb):1:in`blockinirb_binding'from(irb):5:in`each'from(irb):5from/Users/jstillwell/.rv