0
bool HuffmanNode::Compare::operator()(const HuffmanNode &n1, const HuffmanNode &n2) const
{
    if (n1.frequency == n2.frequency) {
        return lessThan ? n1.character < n2.character : n1.character >= n2.character;
    } else {
        return lessThan ? n1.frequency < n2.frequency : n1.frequency >= n2.frequency;
    }
}

bool HuffmanNode::Compare::operator()(const HuffmanNode *n1, const HuffmanNode *n2) const
{
    return operator()(*n1, *n2);
}

Here I have a compare function from a compare object that is within another object (HuffmanNode). I want to pass the compare function to another object through a template:

HeapQueue<HuffmanNode, HuffmanNode::Compare> queue;

This doesn't seem to work and I've even tried using the operator function.

What is the proper format for this? Thanks.

Here is my compiler error

/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1826:31: error: 
      no matching constructor for initialization of 'HuffmanNode'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1718:18: note: 
      in instantiation of function template specialization
      'std::__1::allocator<HuffmanNode>::construct<HuffmanNode>' requested here
            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
                 ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1561:14: note: 
      in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<HuffmanNode>
      >::__construct<HuffmanNode>' requested here
            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
             ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:1030:25: note: 
      in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<HuffmanNode>
      >::construct<HuffmanNode>' requested here
        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
                        ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:1121:9: note: 
      in instantiation of member function 'std::__1::vector<HuffmanNode,
      std::__1::allocator<HuffmanNode> >::__construct_at_end' requested here
        __construct_at_end(__n);
        ^
./HeapQueue.hpp:25:26: note: in instantiation of member function
      'std::__1::vector<HuffmanNode, std::__1::allocator<HuffmanNode> >::vector'
      requested here
  VectorCompleteTree() : V(1) {}
                         ^
./HeapQueue.hpp:46:7: note: in instantiation of member function
      'VectorCompleteTree<HuffmanNode>::VectorCompleteTree' requested here
class HeapQueue
      ^
./HuffmanBase.hpp:8:7: note: candidate constructor (the implicit copy
      constructor) not viable: requires 1 argument, but 0 were provided
class HuffmanNode {
      ^
./HuffmanBase.hpp:8:7: note: candidate constructor (the implicit move
      constructor) not viable: requires 1 argument, but 0 were provided
./HuffmanBase.hpp:11:3: note: candidate constructor not viable: requires 2
      arguments, but 0 were provided
  HuffmanNode(char c, size_t f) : HuffmanNode(c, f, nullptr, nullptr, nu...
  ^
./HuffmanBase.hpp:10:3: note: candidate constructor not viable: requires 5
      arguments, but 0 were provided
  HuffmanNode(char c, size_t f, HuffmanNode *p, HuffmanNode *l, HuffmanN...
  ^
1 error generated.
Dp4897
  • 25
  • 5
  • take a look at this https://stackoverflow.com/questions/45613214/passing-functions-as-arguments-in-c – prhmma Nov 05 '19 at 21:35
  • How do I use object functions as a template argument? – Dp4897 Nov 05 '19 at 21:56
  • What you can pass as non-type template parameters is limited to some allowed cases. According to [this cpp reference](https://en.cppreference.com/w/cpp/language/template_parameters) one of the allowed cases is a pointer to function or pointer to member function. That is probably your best bet. – darcamo Nov 05 '19 at 22:13
  • @darcamo Im not allowed to change anything from the first code snippet for this assignment – Dp4897 Nov 05 '19 at 22:22
  • The error message says that `HuffmanBase` doesn't have a default constructor. – Indiana Kernick Nov 05 '19 at 22:52
  • The default constructor of `VectorCompleteTree` is constructing a `std::vector` with one element. That one element is being default constructed. The problem is that `HuffmanNode` doesn't have a default constructor so this fails. It has nothing to do with `HuffmanNode::Compare`. – Indiana Kernick Nov 05 '19 at 22:54
  • Just added a default constructor and it worked without errors, however that HuffmanBase class is provided by my instructor and im not allowed to change that file. Is there a workaround to not having a default constructor? My program compiles fine without this line: HeapQueue queue; – Dp4897 Nov 05 '19 at 23:08
  • @Dp4897 Are you allowed to change `VectorCompleteTree` or `HeapQueue`? Maybe there's a different constructor of `HeapQueue` (other than the default one) that you could use. – Indiana Kernick Nov 05 '19 at 23:23
  • If you can't change anything then maybe you could try `HeapQueue, HuffmanNode::Compare>`. If that doesn't work (because something is trying to copy the `std::unique_ptr`) then you could try `HeapQueue, HuffmanNode::Compare>` – Indiana Kernick Nov 05 '19 at 23:27
  • @Dp4897 We might be able to help you if you give us more information about what you have available (`HeapQueue`, `VectorCompleteTree` and `HuffmanNode`) and precisely what you're allowed to change. – Indiana Kernick Nov 05 '19 at 23:43

1 Answers1

0

Starting from the bottom of the error message, the compiler is trying to do this HuffmanNode{} but failing because HuffmanNode doesn't have a default constructor. The key here is but 0 were provided.

./HuffmanBase.hpp:8:7: note: candidate constructor (the implicit copy
      constructor) not viable: requires 1 argument, but 0 were provided
class HuffmanNode {
      ^
./HuffmanBase.hpp:8:7: note: candidate constructor (the implicit move
      constructor) not viable: requires 1 argument, but 0 were provided
./HuffmanBase.hpp:11:3: note: candidate constructor not viable: requires 2
      arguments, but 0 were provided
  HuffmanNode(char c, size_t f) : HuffmanNode(c, f, nullptr, nullptr, nu...
  ^
./HuffmanBase.hpp:10:3: note: candidate constructor not viable: requires 5
      arguments, but 0 were provided
  HuffmanNode(char c, size_t f, HuffmanNode *p, HuffmanNode *l, HuffmanN...
  ^

The default constructor of HeapQueue is invoking the default constructor of VectorCompleteTree<HuffmanNode>.

./HeapQueue.hpp:46:7: note: in instantiation of member function
      'VectorCompleteTree<HuffmanNode>::VectorCompleteTree' requested here
class HeapQueue

The default constructor of VectorCompleteTree<HuffmanNode> is constructing a std::vector<HuffmanNode> with one element. This one element needs to be default constructed.

./HeapQueue.hpp:25:26: note: in instantiation of member function
      'std::__1::vector<HuffmanNode, std::__1::allocator<HuffmanNode> >::vector'
      requested here
  VectorCompleteTree() : V(1) {}

std::vector<HuffmanNode> is trying to default construct a HuffmanNode but can't.

/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1826:31: error: 
      no matching constructor for initialization of 'HuffmanNode'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1718:18: note: 
      in instantiation of function template specialization
      'std::__1::allocator<HuffmanNode>::construct<HuffmanNode>' requested here
            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
                 ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1561:14: note: 
      in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<HuffmanNode>
      >::__construct<HuffmanNode>' requested here
            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
             ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:1030:25: note: 
      in instantiation of function template specialization
      'std::__1::allocator_traits<std::__1::allocator<HuffmanNode>
      >::construct<HuffmanNode>' requested here
        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
                        ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:1121:9: note: 
      in instantiation of member function 'std::__1::vector<HuffmanNode,
      std::__1::allocator<HuffmanNode> >::__construct_at_end' requested here
        __construct_at_end(__n);

It's all there in the error message! The simple solution would be do give HuffmanNode a default constructor.

Indiana Kernick
  • 5,041
  • 2
  • 20
  • 50