0

I've searched but failed to find the right answer (which is for sure somewhere present).

I have a class A which defines a struct strName which consists of a string and two uints. Now I want to keep and unordered_set of this struct. (And e.g. initialize it in the contructor or somewhere else in class A). The hasher/equality functions are defined as lambda expressions.

A.hpp

#include <set>
#include <unordered_set>
#include <string>

class A
{
  public:
  private:
    typedef struct
    {
        std::string str;
        u_int8_t n1;
        u_int32_t n2;
    }strName;

    constexpr static size_t hashStruct = [](const strName& structObj) -> const size_t 
    {
      size_t hash = 42; //will update this of course to proper hash function
      return hash;
    };
    
    constexpr static bool equalStruct = [](const strName& s0, const strName& s1) -> const bool 
    {
      bool b0 = s0.str == s1.str;
      bool b1 = s0.n1 == s1.n1;
      bool b2 = s0.n2 == s1.n2;
      return (b0 && b1 && b2);
    };
    std::unordered_set<strName, decltype(hashStruct), decltype(equalStruct)> member_i_want_to_declare;
};

main.cpp

#include "A.hpp" 
int main(int argc, char* const argv[])
{  
    A a();
}

When I do this like this, I get as error: error: invalid user-defined conversion from ‘A::<lambda(const A::strName&)>’ to ‘size_t’ {aka ‘long unsigned int’} [-fpermissive]};

Can someone give me some clues what I do wrong? I tried some things like making the lambda expressions static and so, but this give different errors.

Clemens
  • 53
  • 8
  • 1
    [Working demo](https://godbolt.org/z/sbPh46), you have to need c++20 (since lambdas are default constructible). – rafix07 Dec 22 '20 at 09:18
  • @rafix07 I can't use c++20. now I don't really care if lambdas are used or something else. – Clemens Dec 22 '20 at 09:21
  • @Scheff I replaced auto. Result is: error: static assertion failed: hash function must be invocable with an argument of key type – Clemens Dec 22 '20 at 09:22
  • @Scheff I can...give me some time for that I've updated the question without auto and the new error – Clemens Dec 22 '20 at 09:24
  • After using static lambda expressions I get as error: invalid user-defined conversion from ‘A::’ to ‘size_t’ {aka ‘long unsigned int’} – Clemens Dec 22 '20 at 09:35
  • 1
    Sorry. I was hunting the lambda topic too hard. (I very like lambdas as adapters or in-place initialization of const expressions.) But _your_ issue can be solved in C++17 much easier without lambdas: [**Live Demo on coliru**](http://coliru.stacked-crooked.com/a/b40ebc78bfbe0b62) – Scheff's Cat Dec 22 '20 at 09:42
  • I'm afraid I'm stuck on C++11 (and maybe 14, I'll have to check, can't change that). I've changed the example now to the minimal reproducible example – Clemens Dec 22 '20 at 09:43
  • Concerning `A a();`: <-- That's a function declaration, you know? :-) – Scheff's Cat Dec 22 '20 at 09:43
  • ? that's calling the standard constructor (as no constructor is defined) – Clemens Dec 22 '20 at 09:44
  • 1
    No problem: The same [**Live Demo on coliru**](http://coliru.stacked-crooked.com/a/9247dffd3fd14f69) compiles with `-std=c++11` as well. (I would have wondered if not.) – Scheff's Cat Dec 22 '20 at 09:45
  • OK I'll check it out – Clemens Dec 22 '20 at 09:45
  • No it does not. `A a;` makes default construction. `A a();` is a function declaration. (Try to access `a` then you will realize.) – Scheff's Cat Dec 22 '20 at 09:45
  • That demo with the structs instead of the lambdas seams to work at first sight (will later confirm). Thanks a lot! – Clemens Dec 22 '20 at 09:50
  • Does this answer your question? [How do I specify a custom hash function explicitly for unordered\_set by passing a named function?](https://stackoverflow.com/questions/28120908/how-do-i-specify-a-custom-hash-function-explicitly-for-unordered-set-by-passing) – Scheff's Cat Dec 22 '20 at 09:54

0 Answers0