Search code examples
c++xcodeaudiodeep-learningplugins

Compilation issue on mac Error: No matching constructor for initialization of 'wavenet::WaveNet'


I have a Compilation issue on mac, I'm trying to build this Neural Amp Modeler https://github.com/sdatkinson/iPlug2/tree/main/Examples/NAM on a Apple M1 MBP macOS 12.6 / Xcode 14.0

The code in that repository works on Windows but on my machine I get these errors:

Error: No matching constructor for initialization of 'wavenet::WaveNet'

In instantiation of function template specialization:

    'std::make_unique<wavenet::WaveNet, std::vector<wavenet::LayerArrayParams> &, 
const float &, const bool &, nlohmann::basic_json<>, std::vector<float> &>'

In file included from /Users/username/Dev/iPlug2/Examples/NAM/get_dsp.cpp

note: wavenet.h note: candidate constructor not viable: expects an lvalue for 4th argument
note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 5 were provided
note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 5 were provided'

I don't understand why it works on windows, I can post more code if need it and all the files are on the repository, Thanks!


Solution

  • I made a quick guess based on my experiences (Unfortunately, I cannot test it on a Mac).

    Since the compile error comes from get_dsp.cpp we should try to fix it there before trying to change something in the class WaveNet itself.

    The make_unique call is issued in get_dsp.cpp, line 83.

    In line 87 is the 4th parameter to the constructor:

    architecture == "CatWaveNet" ? config["parametric"] : nlohmann::json{}
    

    I guess the default constructed nlohmann::json after the : is the root source of the compile error. This creates an un-named temporary object which is an rvalue. But the constructor requires an lvalue (non-const reference to a nlohmann::json). To fix that we must ensure we pass something which can act as an lvalue, so we need a named object, like this:

    auto my_json = architecture == "CatWaveNet" ? config["parametric"] : nlohmann::json{};
    

    This must be placed before the return statement in line 82 and then use "my_json" as constructor parameter in line 87. The complete changed block will then look like this:

    auto my_json = architecture == "CatWaveNet" ? config["parametric"] : nlohmann::json{};
    return std::make_unique<wavenet::WaveNet>(
      layer_array_params,
      head_scale,
      with_head,
      my_json,
      params
    );
    

    Does it solve the problem?