std::hash specialisation for my own class and use it inside the class












4















I define a class Foo, and would like to have a public member function that takes std::unordered_set<Foo> as parameters type.



To be able to use std::unordered_set<Foo>, I have to specialize std::hash<Foo> in namespace std.



That's ok if I do not try to use std::unordered_set<Foo> as paramter type in Foo member functions.



However, once I want to use std::unordered_set<Foo> as parameter type in Foo member functions, I Have a problem to define the specialization std::hash<Foo>.
If I do it after the Foo declaration, there is an error on Foo declaration because std::hash<Foo> is not defined. It a move std::hash<Foo> definition before, it does not work either because now Foo is unknown. Forward declaration of Foodoes not work in such situation.



Any ideas how to resolve this ?



Here is an example of such a class



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();
}
};
}




Using answers below, here is the code I finally use (I need to place some MY_EXPORT_MACRO because there is dlls):



In file 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;
};


In file 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;
}









share|improve this question

























  • MSVC in VS 2015 does not implement two-phase lookup correctly, so certain templated things working (or not) when they don't (or do) in gcc/clang is basically coincidental. If you're writing new code, you should not rely on this, as it will eventually break.

    – Max Langhof
    Nov 16 '18 at 10:07











  • Yes, I just tried in my real case, and it does no work. So I will fallback to the pointer version

    – Azias
    Nov 16 '18 at 10:19











  • Actually I am stuck because I cannot use to Pointer version neither, because it is not possible to get a Foo* from a std::unordered_set<Foo>::iterator

    – Azias
    Nov 16 '18 at 10:30











  • What's wrong with &*myIt (aside from syntactic awkwardness)?

    – Max Langhof
    Nov 16 '18 at 10:32











  • my bad, actually I have to return Foo const *and not a Foo *, that's why I had problem with the Pointer version.

    – Azias
    Nov 16 '18 at 10:40
















4















I define a class Foo, and would like to have a public member function that takes std::unordered_set<Foo> as parameters type.



To be able to use std::unordered_set<Foo>, I have to specialize std::hash<Foo> in namespace std.



That's ok if I do not try to use std::unordered_set<Foo> as paramter type in Foo member functions.



However, once I want to use std::unordered_set<Foo> as parameter type in Foo member functions, I Have a problem to define the specialization std::hash<Foo>.
If I do it after the Foo declaration, there is an error on Foo declaration because std::hash<Foo> is not defined. It a move std::hash<Foo> definition before, it does not work either because now Foo is unknown. Forward declaration of Foodoes not work in such situation.



Any ideas how to resolve this ?



Here is an example of such a class



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();
}
};
}




Using answers below, here is the code I finally use (I need to place some MY_EXPORT_MACRO because there is dlls):



In file 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;
};


In file 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;
}









share|improve this question

























  • MSVC in VS 2015 does not implement two-phase lookup correctly, so certain templated things working (or not) when they don't (or do) in gcc/clang is basically coincidental. If you're writing new code, you should not rely on this, as it will eventually break.

    – Max Langhof
    Nov 16 '18 at 10:07











  • Yes, I just tried in my real case, and it does no work. So I will fallback to the pointer version

    – Azias
    Nov 16 '18 at 10:19











  • Actually I am stuck because I cannot use to Pointer version neither, because it is not possible to get a Foo* from a std::unordered_set<Foo>::iterator

    – Azias
    Nov 16 '18 at 10:30











  • What's wrong with &*myIt (aside from syntactic awkwardness)?

    – Max Langhof
    Nov 16 '18 at 10:32











  • my bad, actually I have to return Foo const *and not a Foo *, that's why I had problem with the Pointer version.

    – Azias
    Nov 16 '18 at 10:40














4












4








4


0






I define a class Foo, and would like to have a public member function that takes std::unordered_set<Foo> as parameters type.



To be able to use std::unordered_set<Foo>, I have to specialize std::hash<Foo> in namespace std.



That's ok if I do not try to use std::unordered_set<Foo> as paramter type in Foo member functions.



However, once I want to use std::unordered_set<Foo> as parameter type in Foo member functions, I Have a problem to define the specialization std::hash<Foo>.
If I do it after the Foo declaration, there is an error on Foo declaration because std::hash<Foo> is not defined. It a move std::hash<Foo> definition before, it does not work either because now Foo is unknown. Forward declaration of Foodoes not work in such situation.



Any ideas how to resolve this ?



Here is an example of such a class



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();
}
};
}




Using answers below, here is the code I finally use (I need to place some MY_EXPORT_MACRO because there is dlls):



In file 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;
};


In file 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;
}









share|improve this question
















I define a class Foo, and would like to have a public member function that takes std::unordered_set<Foo> as parameters type.



To be able to use std::unordered_set<Foo>, I have to specialize std::hash<Foo> in namespace std.



That's ok if I do not try to use std::unordered_set<Foo> as paramter type in Foo member functions.



However, once I want to use std::unordered_set<Foo> as parameter type in Foo member functions, I Have a problem to define the specialization std::hash<Foo>.
If I do it after the Foo declaration, there is an error on Foo declaration because std::hash<Foo> is not defined. It a move std::hash<Foo> definition before, it does not work either because now Foo is unknown. Forward declaration of Foodoes not work in such situation.



Any ideas how to resolve this ?



Here is an example of such a class



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();
}
};
}




Using answers below, here is the code I finally use (I need to place some MY_EXPORT_MACRO because there is dlls):



In file 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;
};


In file 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;
}






c++ c++11






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 '18 at 13:12







Azias

















asked Nov 16 '18 at 8:27









AziasAzias

10918




10918













  • MSVC in VS 2015 does not implement two-phase lookup correctly, so certain templated things working (or not) when they don't (or do) in gcc/clang is basically coincidental. If you're writing new code, you should not rely on this, as it will eventually break.

    – Max Langhof
    Nov 16 '18 at 10:07











  • Yes, I just tried in my real case, and it does no work. So I will fallback to the pointer version

    – Azias
    Nov 16 '18 at 10:19











  • Actually I am stuck because I cannot use to Pointer version neither, because it is not possible to get a Foo* from a std::unordered_set<Foo>::iterator

    – Azias
    Nov 16 '18 at 10:30











  • What's wrong with &*myIt (aside from syntactic awkwardness)?

    – Max Langhof
    Nov 16 '18 at 10:32











  • my bad, actually I have to return Foo const *and not a Foo *, that's why I had problem with the Pointer version.

    – Azias
    Nov 16 '18 at 10:40



















  • MSVC in VS 2015 does not implement two-phase lookup correctly, so certain templated things working (or not) when they don't (or do) in gcc/clang is basically coincidental. If you're writing new code, you should not rely on this, as it will eventually break.

    – Max Langhof
    Nov 16 '18 at 10:07











  • Yes, I just tried in my real case, and it does no work. So I will fallback to the pointer version

    – Azias
    Nov 16 '18 at 10:19











  • Actually I am stuck because I cannot use to Pointer version neither, because it is not possible to get a Foo* from a std::unordered_set<Foo>::iterator

    – Azias
    Nov 16 '18 at 10:30











  • What's wrong with &*myIt (aside from syntactic awkwardness)?

    – Max Langhof
    Nov 16 '18 at 10:32











  • my bad, actually I have to return Foo const *and not a Foo *, that's why I had problem with the Pointer version.

    – Azias
    Nov 16 '18 at 10:40

















MSVC in VS 2015 does not implement two-phase lookup correctly, so certain templated things working (or not) when they don't (or do) in gcc/clang is basically coincidental. If you're writing new code, you should not rely on this, as it will eventually break.

– Max Langhof
Nov 16 '18 at 10:07





MSVC in VS 2015 does not implement two-phase lookup correctly, so certain templated things working (or not) when they don't (or do) in gcc/clang is basically coincidental. If you're writing new code, you should not rely on this, as it will eventually break.

– Max Langhof
Nov 16 '18 at 10:07













Yes, I just tried in my real case, and it does no work. So I will fallback to the pointer version

– Azias
Nov 16 '18 at 10:19





Yes, I just tried in my real case, and it does no work. So I will fallback to the pointer version

– Azias
Nov 16 '18 at 10:19













Actually I am stuck because I cannot use to Pointer version neither, because it is not possible to get a Foo* from a std::unordered_set<Foo>::iterator

– Azias
Nov 16 '18 at 10:30





Actually I am stuck because I cannot use to Pointer version neither, because it is not possible to get a Foo* from a std::unordered_set<Foo>::iterator

– Azias
Nov 16 '18 at 10:30













What's wrong with &*myIt (aside from syntactic awkwardness)?

– Max Langhof
Nov 16 '18 at 10:32





What's wrong with &*myIt (aside from syntactic awkwardness)?

– Max Langhof
Nov 16 '18 at 10:32













my bad, actually I have to return Foo const *and not a Foo *, that's why I had problem with the Pointer version.

– Azias
Nov 16 '18 at 10:40





my bad, actually I have to return Foo const *and not a Foo *, that's why I had problem with the Pointer version.

– Azias
Nov 16 '18 at 10:40












4 Answers
4






active

oldest

votes


















3














The real problem in your example is that you want to use std::unordered_set<Foo>::iterator as return type. This requires that unordered_set<Foo> is fully instantiated, which requires Foo (and std::hash<Foo>) to be a complete class. But Foo is only a complete class at the end of its definition. Note that this problem does not exist with the by-reference function parameter, where the compiler does not have to fully instantiate the referenced class.



As originally suggested by @MrTux, you can fix everything else with forward declarations:



class Foo;

template<>
struct std::hash<Foo>;


If you return a Foo* instead, everything works:



Demo



Whether that works for your design is another question.





I should note that you can have std::hash<Foo> be fully defined before Foo's definition:



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();
}


That would allow you to return e.g. std::unordered_set<Foo> from methods in Foo, but it still does not fix the core issue of Foo being incomplete (and thus std::unordered_set<Foo>::iterator being unavailable) during its own definition.






share|improve this answer


























  • Thank you, it effectively works with forward declaration if change the signature of findClosest to Foo* findClosest(std::unordered_set<Foo> const &others). So it is an interesting solution for me. However if someone had a solution to be able to return an iterator (because it seems more clean for me), it would be perfect.

    – Azias
    Nov 16 '18 at 9:20








  • 2





    You can return an iterator by writing auto findClosest(...) { return std::end(...); } Like in here

    – Julian vD
    Nov 16 '18 at 9:25













  • @Julian actually it does not work in my real case, because class Foo and its use are in different dlls, and I get an error "a function that returns 'auto' cannot be used before it is defined". There is solutions for that but I do not want to deal with.

    – Azias
    Nov 16 '18 at 10:35













  • @Azias Well, in the background auto is somewhat like a template, the easiest solution would to just put the definition of findClosest in the header file. That way at the moment you include Foo, findClosest is defined. That's why many, if not all, of the standard containers are simply put in header files.

    – Julian vD
    Nov 16 '18 at 11:16



















1














I see that you tagged the Question as C++11 (so we cannot rely on type deduction for the return type), so here is a solution that returns a const_iterator (others is const):



#include <unordered_set>

class Foo;

namespace std
{
template <>
struct hash<Foo>
{
size_t operator()(Foo const & bar) const;
};
}

class Foo
{
public:
template <class Hash>
typename std::unordered_set<Foo, Hash>::const_iterator findClosest(std::unordered_set<Foo, Hash> const &others)
{
return std::end(others);
}

size_t hashValue() const {
return std::hash<int>()(m_Member);
}

private:
int m_Member;
};

size_t std::hash<Foo>::operator()(Foo const & bar) const
{
return bar.hashValue();
}

int main()
{
Foo f;
std::unordered_set<Foo> fs;
f.findClosest(fs);
}





share|improve this answer
























  • you are right, I must return const_iterator

    – Azias
    Nov 16 '18 at 9:53











  • @Azias It actually makes no difference because both iterator and const_iterator are const iterators (and may be the same type) for std::set and std::unordered_set: "Container elements may not be modified (even by non const iterators) since modification could change an element's hash and corrupt the container.".

    – Max Langhof
    Nov 16 '18 at 9:58





















1














You might find the code is clearer and easier to maintain if you move the concerns of hashing Foo and finding closest distance into free functions.



Here's an example using boost::hash protocols (which I find to be very helpful)



#include <unordered_set>
#include <boost/functional/hash.hpp>

class Foo
{
public:

// return a tuple of immutable values which should be hashed in order to
// compute this object's hash value
auto hashy_stuff() const // -> std::tuple<const int&> // if you are < c++14
{
return std::tie(m_Member);
}

private:
int m_Member;
};

// implement the boost::hash hash_value protocol in terms of hashy_stuff
// (we win because now it's DRY and works with all boost hash functions)
auto hash_value(Foo const& foo) -> std::size_t { return boost::hash_value(foo.hashy_stuff()); }

// implement std::hash in terms of boost::hash (again, DRY because it automatically
// uses hash_value())
namespace std { template<> struct hash<Foo> : ::boost::hash<Foo> {}; }

// implement findClosest as a free function. Its concerns are tangential to
// the Foo-ness of a Foo.
std::unordered_set<Foo>::const_iterator
findClosest(Foo const& /*foo*/, std::unordered_set<Foo> const &others)
{
// implementation here in terms of public interface
return std::end(others);
}

extern auto make_foos() -> std::unordered_set<Foo>;
extern auto make_foo() -> Foo;

bool test()
{
auto foos = make_foos();
auto foo = make_foo();

auto i = findClosest(foo, foos);

return i != end(foos);
}





share|improve this answer































    -1














    Instead of specializing template in std namespace you can try below method if you like that.



    #include <iostream>
    #include <unordered_set>
    struct FooHash;
    class Foo {
    public:
    Foo(){
    }
    ~Foo(){
    }
    friend FooHash;
    private:
    std::string m_str;
    };
    struct FooHash
    {
    std::size_t operator()(Foo const& f) const noexcept{
    return std::hash<std::string>{}(f.m_str);
    }
    };
    int main(){
    std::unordered_set<Foo,FooHash> fSet;
    return 0;
    }


    Live Code






    share|improve this answer
























    • This completely ignores the core of the question: Using std::unordered_set<Foo> in the interface of Foo.

      – Max Langhof
      Nov 16 '18 at 8:58











    • @MaxLanghof Sorry My mistake

      – Manthan Tilva
      Nov 16 '18 at 9:15











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53334015%2fstdhash-specialisation-for-my-own-class-and-use-it-inside-the-class%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    The real problem in your example is that you want to use std::unordered_set<Foo>::iterator as return type. This requires that unordered_set<Foo> is fully instantiated, which requires Foo (and std::hash<Foo>) to be a complete class. But Foo is only a complete class at the end of its definition. Note that this problem does not exist with the by-reference function parameter, where the compiler does not have to fully instantiate the referenced class.



    As originally suggested by @MrTux, you can fix everything else with forward declarations:



    class Foo;

    template<>
    struct std::hash<Foo>;


    If you return a Foo* instead, everything works:



    Demo



    Whether that works for your design is another question.





    I should note that you can have std::hash<Foo> be fully defined before Foo's definition:



    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();
    }


    That would allow you to return e.g. std::unordered_set<Foo> from methods in Foo, but it still does not fix the core issue of Foo being incomplete (and thus std::unordered_set<Foo>::iterator being unavailable) during its own definition.






    share|improve this answer


























    • Thank you, it effectively works with forward declaration if change the signature of findClosest to Foo* findClosest(std::unordered_set<Foo> const &others). So it is an interesting solution for me. However if someone had a solution to be able to return an iterator (because it seems more clean for me), it would be perfect.

      – Azias
      Nov 16 '18 at 9:20








    • 2





      You can return an iterator by writing auto findClosest(...) { return std::end(...); } Like in here

      – Julian vD
      Nov 16 '18 at 9:25













    • @Julian actually it does not work in my real case, because class Foo and its use are in different dlls, and I get an error "a function that returns 'auto' cannot be used before it is defined". There is solutions for that but I do not want to deal with.

      – Azias
      Nov 16 '18 at 10:35













    • @Azias Well, in the background auto is somewhat like a template, the easiest solution would to just put the definition of findClosest in the header file. That way at the moment you include Foo, findClosest is defined. That's why many, if not all, of the standard containers are simply put in header files.

      – Julian vD
      Nov 16 '18 at 11:16
















    3














    The real problem in your example is that you want to use std::unordered_set<Foo>::iterator as return type. This requires that unordered_set<Foo> is fully instantiated, which requires Foo (and std::hash<Foo>) to be a complete class. But Foo is only a complete class at the end of its definition. Note that this problem does not exist with the by-reference function parameter, where the compiler does not have to fully instantiate the referenced class.



    As originally suggested by @MrTux, you can fix everything else with forward declarations:



    class Foo;

    template<>
    struct std::hash<Foo>;


    If you return a Foo* instead, everything works:



    Demo



    Whether that works for your design is another question.





    I should note that you can have std::hash<Foo> be fully defined before Foo's definition:



    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();
    }


    That would allow you to return e.g. std::unordered_set<Foo> from methods in Foo, but it still does not fix the core issue of Foo being incomplete (and thus std::unordered_set<Foo>::iterator being unavailable) during its own definition.






    share|improve this answer


























    • Thank you, it effectively works with forward declaration if change the signature of findClosest to Foo* findClosest(std::unordered_set<Foo> const &others). So it is an interesting solution for me. However if someone had a solution to be able to return an iterator (because it seems more clean for me), it would be perfect.

      – Azias
      Nov 16 '18 at 9:20








    • 2





      You can return an iterator by writing auto findClosest(...) { return std::end(...); } Like in here

      – Julian vD
      Nov 16 '18 at 9:25













    • @Julian actually it does not work in my real case, because class Foo and its use are in different dlls, and I get an error "a function that returns 'auto' cannot be used before it is defined". There is solutions for that but I do not want to deal with.

      – Azias
      Nov 16 '18 at 10:35













    • @Azias Well, in the background auto is somewhat like a template, the easiest solution would to just put the definition of findClosest in the header file. That way at the moment you include Foo, findClosest is defined. That's why many, if not all, of the standard containers are simply put in header files.

      – Julian vD
      Nov 16 '18 at 11:16














    3












    3








    3







    The real problem in your example is that you want to use std::unordered_set<Foo>::iterator as return type. This requires that unordered_set<Foo> is fully instantiated, which requires Foo (and std::hash<Foo>) to be a complete class. But Foo is only a complete class at the end of its definition. Note that this problem does not exist with the by-reference function parameter, where the compiler does not have to fully instantiate the referenced class.



    As originally suggested by @MrTux, you can fix everything else with forward declarations:



    class Foo;

    template<>
    struct std::hash<Foo>;


    If you return a Foo* instead, everything works:



    Demo



    Whether that works for your design is another question.





    I should note that you can have std::hash<Foo> be fully defined before Foo's definition:



    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();
    }


    That would allow you to return e.g. std::unordered_set<Foo> from methods in Foo, but it still does not fix the core issue of Foo being incomplete (and thus std::unordered_set<Foo>::iterator being unavailable) during its own definition.






    share|improve this answer















    The real problem in your example is that you want to use std::unordered_set<Foo>::iterator as return type. This requires that unordered_set<Foo> is fully instantiated, which requires Foo (and std::hash<Foo>) to be a complete class. But Foo is only a complete class at the end of its definition. Note that this problem does not exist with the by-reference function parameter, where the compiler does not have to fully instantiate the referenced class.



    As originally suggested by @MrTux, you can fix everything else with forward declarations:



    class Foo;

    template<>
    struct std::hash<Foo>;


    If you return a Foo* instead, everything works:



    Demo



    Whether that works for your design is another question.





    I should note that you can have std::hash<Foo> be fully defined before Foo's definition:



    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();
    }


    That would allow you to return e.g. std::unordered_set<Foo> from methods in Foo, but it still does not fix the core issue of Foo being incomplete (and thus std::unordered_set<Foo>::iterator being unavailable) during its own definition.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 16 '18 at 9:13

























    answered Nov 16 '18 at 8:57









    Max LanghofMax Langhof

    9,1911537




    9,1911537













    • Thank you, it effectively works with forward declaration if change the signature of findClosest to Foo* findClosest(std::unordered_set<Foo> const &others). So it is an interesting solution for me. However if someone had a solution to be able to return an iterator (because it seems more clean for me), it would be perfect.

      – Azias
      Nov 16 '18 at 9:20








    • 2





      You can return an iterator by writing auto findClosest(...) { return std::end(...); } Like in here

      – Julian vD
      Nov 16 '18 at 9:25













    • @Julian actually it does not work in my real case, because class Foo and its use are in different dlls, and I get an error "a function that returns 'auto' cannot be used before it is defined". There is solutions for that but I do not want to deal with.

      – Azias
      Nov 16 '18 at 10:35













    • @Azias Well, in the background auto is somewhat like a template, the easiest solution would to just put the definition of findClosest in the header file. That way at the moment you include Foo, findClosest is defined. That's why many, if not all, of the standard containers are simply put in header files.

      – Julian vD
      Nov 16 '18 at 11:16



















    • Thank you, it effectively works with forward declaration if change the signature of findClosest to Foo* findClosest(std::unordered_set<Foo> const &others). So it is an interesting solution for me. However if someone had a solution to be able to return an iterator (because it seems more clean for me), it would be perfect.

      – Azias
      Nov 16 '18 at 9:20








    • 2





      You can return an iterator by writing auto findClosest(...) { return std::end(...); } Like in here

      – Julian vD
      Nov 16 '18 at 9:25













    • @Julian actually it does not work in my real case, because class Foo and its use are in different dlls, and I get an error "a function that returns 'auto' cannot be used before it is defined". There is solutions for that but I do not want to deal with.

      – Azias
      Nov 16 '18 at 10:35













    • @Azias Well, in the background auto is somewhat like a template, the easiest solution would to just put the definition of findClosest in the header file. That way at the moment you include Foo, findClosest is defined. That's why many, if not all, of the standard containers are simply put in header files.

      – Julian vD
      Nov 16 '18 at 11:16

















    Thank you, it effectively works with forward declaration if change the signature of findClosest to Foo* findClosest(std::unordered_set<Foo> const &others). So it is an interesting solution for me. However if someone had a solution to be able to return an iterator (because it seems more clean for me), it would be perfect.

    – Azias
    Nov 16 '18 at 9:20







    Thank you, it effectively works with forward declaration if change the signature of findClosest to Foo* findClosest(std::unordered_set<Foo> const &others). So it is an interesting solution for me. However if someone had a solution to be able to return an iterator (because it seems more clean for me), it would be perfect.

    – Azias
    Nov 16 '18 at 9:20






    2




    2





    You can return an iterator by writing auto findClosest(...) { return std::end(...); } Like in here

    – Julian vD
    Nov 16 '18 at 9:25







    You can return an iterator by writing auto findClosest(...) { return std::end(...); } Like in here

    – Julian vD
    Nov 16 '18 at 9:25















    @Julian actually it does not work in my real case, because class Foo and its use are in different dlls, and I get an error "a function that returns 'auto' cannot be used before it is defined". There is solutions for that but I do not want to deal with.

    – Azias
    Nov 16 '18 at 10:35







    @Julian actually it does not work in my real case, because class Foo and its use are in different dlls, and I get an error "a function that returns 'auto' cannot be used before it is defined". There is solutions for that but I do not want to deal with.

    – Azias
    Nov 16 '18 at 10:35















    @Azias Well, in the background auto is somewhat like a template, the easiest solution would to just put the definition of findClosest in the header file. That way at the moment you include Foo, findClosest is defined. That's why many, if not all, of the standard containers are simply put in header files.

    – Julian vD
    Nov 16 '18 at 11:16





    @Azias Well, in the background auto is somewhat like a template, the easiest solution would to just put the definition of findClosest in the header file. That way at the moment you include Foo, findClosest is defined. That's why many, if not all, of the standard containers are simply put in header files.

    – Julian vD
    Nov 16 '18 at 11:16













    1














    I see that you tagged the Question as C++11 (so we cannot rely on type deduction for the return type), so here is a solution that returns a const_iterator (others is const):



    #include <unordered_set>

    class Foo;

    namespace std
    {
    template <>
    struct hash<Foo>
    {
    size_t operator()(Foo const & bar) const;
    };
    }

    class Foo
    {
    public:
    template <class Hash>
    typename std::unordered_set<Foo, Hash>::const_iterator findClosest(std::unordered_set<Foo, Hash> const &others)
    {
    return std::end(others);
    }

    size_t hashValue() const {
    return std::hash<int>()(m_Member);
    }

    private:
    int m_Member;
    };

    size_t std::hash<Foo>::operator()(Foo const & bar) const
    {
    return bar.hashValue();
    }

    int main()
    {
    Foo f;
    std::unordered_set<Foo> fs;
    f.findClosest(fs);
    }





    share|improve this answer
























    • you are right, I must return const_iterator

      – Azias
      Nov 16 '18 at 9:53











    • @Azias It actually makes no difference because both iterator and const_iterator are const iterators (and may be the same type) for std::set and std::unordered_set: "Container elements may not be modified (even by non const iterators) since modification could change an element's hash and corrupt the container.".

      – Max Langhof
      Nov 16 '18 at 9:58


















    1














    I see that you tagged the Question as C++11 (so we cannot rely on type deduction for the return type), so here is a solution that returns a const_iterator (others is const):



    #include <unordered_set>

    class Foo;

    namespace std
    {
    template <>
    struct hash<Foo>
    {
    size_t operator()(Foo const & bar) const;
    };
    }

    class Foo
    {
    public:
    template <class Hash>
    typename std::unordered_set<Foo, Hash>::const_iterator findClosest(std::unordered_set<Foo, Hash> const &others)
    {
    return std::end(others);
    }

    size_t hashValue() const {
    return std::hash<int>()(m_Member);
    }

    private:
    int m_Member;
    };

    size_t std::hash<Foo>::operator()(Foo const & bar) const
    {
    return bar.hashValue();
    }

    int main()
    {
    Foo f;
    std::unordered_set<Foo> fs;
    f.findClosest(fs);
    }





    share|improve this answer
























    • you are right, I must return const_iterator

      – Azias
      Nov 16 '18 at 9:53











    • @Azias It actually makes no difference because both iterator and const_iterator are const iterators (and may be the same type) for std::set and std::unordered_set: "Container elements may not be modified (even by non const iterators) since modification could change an element's hash and corrupt the container.".

      – Max Langhof
      Nov 16 '18 at 9:58
















    1












    1








    1







    I see that you tagged the Question as C++11 (so we cannot rely on type deduction for the return type), so here is a solution that returns a const_iterator (others is const):



    #include <unordered_set>

    class Foo;

    namespace std
    {
    template <>
    struct hash<Foo>
    {
    size_t operator()(Foo const & bar) const;
    };
    }

    class Foo
    {
    public:
    template <class Hash>
    typename std::unordered_set<Foo, Hash>::const_iterator findClosest(std::unordered_set<Foo, Hash> const &others)
    {
    return std::end(others);
    }

    size_t hashValue() const {
    return std::hash<int>()(m_Member);
    }

    private:
    int m_Member;
    };

    size_t std::hash<Foo>::operator()(Foo const & bar) const
    {
    return bar.hashValue();
    }

    int main()
    {
    Foo f;
    std::unordered_set<Foo> fs;
    f.findClosest(fs);
    }





    share|improve this answer













    I see that you tagged the Question as C++11 (so we cannot rely on type deduction for the return type), so here is a solution that returns a const_iterator (others is const):



    #include <unordered_set>

    class Foo;

    namespace std
    {
    template <>
    struct hash<Foo>
    {
    size_t operator()(Foo const & bar) const;
    };
    }

    class Foo
    {
    public:
    template <class Hash>
    typename std::unordered_set<Foo, Hash>::const_iterator findClosest(std::unordered_set<Foo, Hash> const &others)
    {
    return std::end(others);
    }

    size_t hashValue() const {
    return std::hash<int>()(m_Member);
    }

    private:
    int m_Member;
    };

    size_t std::hash<Foo>::operator()(Foo const & bar) const
    {
    return bar.hashValue();
    }

    int main()
    {
    Foo f;
    std::unordered_set<Foo> fs;
    f.findClosest(fs);
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 16 '18 at 9:48









    JonasJonas

    5,79982442




    5,79982442













    • you are right, I must return const_iterator

      – Azias
      Nov 16 '18 at 9:53











    • @Azias It actually makes no difference because both iterator and const_iterator are const iterators (and may be the same type) for std::set and std::unordered_set: "Container elements may not be modified (even by non const iterators) since modification could change an element's hash and corrupt the container.".

      – Max Langhof
      Nov 16 '18 at 9:58





















    • you are right, I must return const_iterator

      – Azias
      Nov 16 '18 at 9:53











    • @Azias It actually makes no difference because both iterator and const_iterator are const iterators (and may be the same type) for std::set and std::unordered_set: "Container elements may not be modified (even by non const iterators) since modification could change an element's hash and corrupt the container.".

      – Max Langhof
      Nov 16 '18 at 9:58



















    you are right, I must return const_iterator

    – Azias
    Nov 16 '18 at 9:53





    you are right, I must return const_iterator

    – Azias
    Nov 16 '18 at 9:53













    @Azias It actually makes no difference because both iterator and const_iterator are const iterators (and may be the same type) for std::set and std::unordered_set: "Container elements may not be modified (even by non const iterators) since modification could change an element's hash and corrupt the container.".

    – Max Langhof
    Nov 16 '18 at 9:58







    @Azias It actually makes no difference because both iterator and const_iterator are const iterators (and may be the same type) for std::set and std::unordered_set: "Container elements may not be modified (even by non const iterators) since modification could change an element's hash and corrupt the container.".

    – Max Langhof
    Nov 16 '18 at 9:58













    1














    You might find the code is clearer and easier to maintain if you move the concerns of hashing Foo and finding closest distance into free functions.



    Here's an example using boost::hash protocols (which I find to be very helpful)



    #include <unordered_set>
    #include <boost/functional/hash.hpp>

    class Foo
    {
    public:

    // return a tuple of immutable values which should be hashed in order to
    // compute this object's hash value
    auto hashy_stuff() const // -> std::tuple<const int&> // if you are < c++14
    {
    return std::tie(m_Member);
    }

    private:
    int m_Member;
    };

    // implement the boost::hash hash_value protocol in terms of hashy_stuff
    // (we win because now it's DRY and works with all boost hash functions)
    auto hash_value(Foo const& foo) -> std::size_t { return boost::hash_value(foo.hashy_stuff()); }

    // implement std::hash in terms of boost::hash (again, DRY because it automatically
    // uses hash_value())
    namespace std { template<> struct hash<Foo> : ::boost::hash<Foo> {}; }

    // implement findClosest as a free function. Its concerns are tangential to
    // the Foo-ness of a Foo.
    std::unordered_set<Foo>::const_iterator
    findClosest(Foo const& /*foo*/, std::unordered_set<Foo> const &others)
    {
    // implementation here in terms of public interface
    return std::end(others);
    }

    extern auto make_foos() -> std::unordered_set<Foo>;
    extern auto make_foo() -> Foo;

    bool test()
    {
    auto foos = make_foos();
    auto foo = make_foo();

    auto i = findClosest(foo, foos);

    return i != end(foos);
    }





    share|improve this answer




























      1














      You might find the code is clearer and easier to maintain if you move the concerns of hashing Foo and finding closest distance into free functions.



      Here's an example using boost::hash protocols (which I find to be very helpful)



      #include <unordered_set>
      #include <boost/functional/hash.hpp>

      class Foo
      {
      public:

      // return a tuple of immutable values which should be hashed in order to
      // compute this object's hash value
      auto hashy_stuff() const // -> std::tuple<const int&> // if you are < c++14
      {
      return std::tie(m_Member);
      }

      private:
      int m_Member;
      };

      // implement the boost::hash hash_value protocol in terms of hashy_stuff
      // (we win because now it's DRY and works with all boost hash functions)
      auto hash_value(Foo const& foo) -> std::size_t { return boost::hash_value(foo.hashy_stuff()); }

      // implement std::hash in terms of boost::hash (again, DRY because it automatically
      // uses hash_value())
      namespace std { template<> struct hash<Foo> : ::boost::hash<Foo> {}; }

      // implement findClosest as a free function. Its concerns are tangential to
      // the Foo-ness of a Foo.
      std::unordered_set<Foo>::const_iterator
      findClosest(Foo const& /*foo*/, std::unordered_set<Foo> const &others)
      {
      // implementation here in terms of public interface
      return std::end(others);
      }

      extern auto make_foos() -> std::unordered_set<Foo>;
      extern auto make_foo() -> Foo;

      bool test()
      {
      auto foos = make_foos();
      auto foo = make_foo();

      auto i = findClosest(foo, foos);

      return i != end(foos);
      }





      share|improve this answer


























        1












        1








        1







        You might find the code is clearer and easier to maintain if you move the concerns of hashing Foo and finding closest distance into free functions.



        Here's an example using boost::hash protocols (which I find to be very helpful)



        #include <unordered_set>
        #include <boost/functional/hash.hpp>

        class Foo
        {
        public:

        // return a tuple of immutable values which should be hashed in order to
        // compute this object's hash value
        auto hashy_stuff() const // -> std::tuple<const int&> // if you are < c++14
        {
        return std::tie(m_Member);
        }

        private:
        int m_Member;
        };

        // implement the boost::hash hash_value protocol in terms of hashy_stuff
        // (we win because now it's DRY and works with all boost hash functions)
        auto hash_value(Foo const& foo) -> std::size_t { return boost::hash_value(foo.hashy_stuff()); }

        // implement std::hash in terms of boost::hash (again, DRY because it automatically
        // uses hash_value())
        namespace std { template<> struct hash<Foo> : ::boost::hash<Foo> {}; }

        // implement findClosest as a free function. Its concerns are tangential to
        // the Foo-ness of a Foo.
        std::unordered_set<Foo>::const_iterator
        findClosest(Foo const& /*foo*/, std::unordered_set<Foo> const &others)
        {
        // implementation here in terms of public interface
        return std::end(others);
        }

        extern auto make_foos() -> std::unordered_set<Foo>;
        extern auto make_foo() -> Foo;

        bool test()
        {
        auto foos = make_foos();
        auto foo = make_foo();

        auto i = findClosest(foo, foos);

        return i != end(foos);
        }





        share|improve this answer













        You might find the code is clearer and easier to maintain if you move the concerns of hashing Foo and finding closest distance into free functions.



        Here's an example using boost::hash protocols (which I find to be very helpful)



        #include <unordered_set>
        #include <boost/functional/hash.hpp>

        class Foo
        {
        public:

        // return a tuple of immutable values which should be hashed in order to
        // compute this object's hash value
        auto hashy_stuff() const // -> std::tuple<const int&> // if you are < c++14
        {
        return std::tie(m_Member);
        }

        private:
        int m_Member;
        };

        // implement the boost::hash hash_value protocol in terms of hashy_stuff
        // (we win because now it's DRY and works with all boost hash functions)
        auto hash_value(Foo const& foo) -> std::size_t { return boost::hash_value(foo.hashy_stuff()); }

        // implement std::hash in terms of boost::hash (again, DRY because it automatically
        // uses hash_value())
        namespace std { template<> struct hash<Foo> : ::boost::hash<Foo> {}; }

        // implement findClosest as a free function. Its concerns are tangential to
        // the Foo-ness of a Foo.
        std::unordered_set<Foo>::const_iterator
        findClosest(Foo const& /*foo*/, std::unordered_set<Foo> const &others)
        {
        // implementation here in terms of public interface
        return std::end(others);
        }

        extern auto make_foos() -> std::unordered_set<Foo>;
        extern auto make_foo() -> Foo;

        bool test()
        {
        auto foos = make_foos();
        auto foo = make_foo();

        auto i = findClosest(foo, foos);

        return i != end(foos);
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 16 '18 at 9:51









        Richard HodgesRichard Hodges

        55.4k657100




        55.4k657100























            -1














            Instead of specializing template in std namespace you can try below method if you like that.



            #include <iostream>
            #include <unordered_set>
            struct FooHash;
            class Foo {
            public:
            Foo(){
            }
            ~Foo(){
            }
            friend FooHash;
            private:
            std::string m_str;
            };
            struct FooHash
            {
            std::size_t operator()(Foo const& f) const noexcept{
            return std::hash<std::string>{}(f.m_str);
            }
            };
            int main(){
            std::unordered_set<Foo,FooHash> fSet;
            return 0;
            }


            Live Code






            share|improve this answer
























            • This completely ignores the core of the question: Using std::unordered_set<Foo> in the interface of Foo.

              – Max Langhof
              Nov 16 '18 at 8:58











            • @MaxLanghof Sorry My mistake

              – Manthan Tilva
              Nov 16 '18 at 9:15
















            -1














            Instead of specializing template in std namespace you can try below method if you like that.



            #include <iostream>
            #include <unordered_set>
            struct FooHash;
            class Foo {
            public:
            Foo(){
            }
            ~Foo(){
            }
            friend FooHash;
            private:
            std::string m_str;
            };
            struct FooHash
            {
            std::size_t operator()(Foo const& f) const noexcept{
            return std::hash<std::string>{}(f.m_str);
            }
            };
            int main(){
            std::unordered_set<Foo,FooHash> fSet;
            return 0;
            }


            Live Code






            share|improve this answer
























            • This completely ignores the core of the question: Using std::unordered_set<Foo> in the interface of Foo.

              – Max Langhof
              Nov 16 '18 at 8:58











            • @MaxLanghof Sorry My mistake

              – Manthan Tilva
              Nov 16 '18 at 9:15














            -1












            -1








            -1







            Instead of specializing template in std namespace you can try below method if you like that.



            #include <iostream>
            #include <unordered_set>
            struct FooHash;
            class Foo {
            public:
            Foo(){
            }
            ~Foo(){
            }
            friend FooHash;
            private:
            std::string m_str;
            };
            struct FooHash
            {
            std::size_t operator()(Foo const& f) const noexcept{
            return std::hash<std::string>{}(f.m_str);
            }
            };
            int main(){
            std::unordered_set<Foo,FooHash> fSet;
            return 0;
            }


            Live Code






            share|improve this answer













            Instead of specializing template in std namespace you can try below method if you like that.



            #include <iostream>
            #include <unordered_set>
            struct FooHash;
            class Foo {
            public:
            Foo(){
            }
            ~Foo(){
            }
            friend FooHash;
            private:
            std::string m_str;
            };
            struct FooHash
            {
            std::size_t operator()(Foo const& f) const noexcept{
            return std::hash<std::string>{}(f.m_str);
            }
            };
            int main(){
            std::unordered_set<Foo,FooHash> fSet;
            return 0;
            }


            Live Code







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 16 '18 at 8:54









            Manthan TilvaManthan Tilva

            1,296823




            1,296823













            • This completely ignores the core of the question: Using std::unordered_set<Foo> in the interface of Foo.

              – Max Langhof
              Nov 16 '18 at 8:58











            • @MaxLanghof Sorry My mistake

              – Manthan Tilva
              Nov 16 '18 at 9:15



















            • This completely ignores the core of the question: Using std::unordered_set<Foo> in the interface of Foo.

              – Max Langhof
              Nov 16 '18 at 8:58











            • @MaxLanghof Sorry My mistake

              – Manthan Tilva
              Nov 16 '18 at 9:15

















            This completely ignores the core of the question: Using std::unordered_set<Foo> in the interface of Foo.

            – Max Langhof
            Nov 16 '18 at 8:58





            This completely ignores the core of the question: Using std::unordered_set<Foo> in the interface of Foo.

            – Max Langhof
            Nov 16 '18 at 8:58













            @MaxLanghof Sorry My mistake

            – Manthan Tilva
            Nov 16 '18 at 9:15





            @MaxLanghof Sorry My mistake

            – Manthan Tilva
            Nov 16 '18 at 9:15


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53334015%2fstdhash-specialisation-for-my-own-class-and-use-it-inside-the-class%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)