skip to Main Content

I’m using emplace_back to add structs to a std::vector as follows:

struct ConfigurableShaderParameter
{
    std::string variableName;
    std::string description;
    float defaultValue;
    float min;
    float max;
    float step;
    float value;
};

std::vector<ConfigurableShaderParameter> parameters;

std::string variableName, description;
float defaultValue, min, max, step;
// Initialize the above variables
parameters.emplace_back(variableName, description, defaultValue, min, max, step, defaultValue);

The project is built using CMake and C++20 and it’s cross-platform: it compiles fine under Ubuntu and Windows but I cannot get it to compile under macos-latest (I’m using github actions, I don’t have access to a mac).

This is the error message:

/Users/runner/work/epoch/epoch/src/frontend/src/ConfigurableShader.cpp:41:30: note: in instantiation of function template specialization 'std::vector<epoch::frontend::ConfigurableShaderParameter>::emplace_back<std::string &, std::string &, float &, float &, float &, float &, float &>' requested here
                m_parameters.emplace_back(variableName, description, defaultValue, min, max, step, defaultValue);
                             ^
/Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/construct_at.h:35:16: note: candidate template ignored: substitution failure [with _Tp = epoch::frontend::ConfigurableShaderParameter, _Args = <std::string &, std::string &, float &, float &, float &, float &, float &>]: no matching constructor for initialization of 'epoch::frontend::ConfigurableShaderParameter'
constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
               ^
1 error generated.

My main CMakeLists.txt file includes the following directives and nothing else:

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

The project is open-source, so if you wish you can see the entire failed build message here: https://github.com/ghidosoft/epoch/actions/runs/7992320133/job/21825555388?pr=1#step:5:226

What can I do to fix the error?

Thank you.

2

Answers


  1. emplace_back() is looking for a constructor that doesn’t exist in the struct:

    https://onlinegdb.com/4JjUZWNy5

    error: no matching function for call to ‘ConfigurableShaderParameter::ConfigurableShaderParameter(std::__cxx11::basic_string&, std::__cxx11::basic_string&, float&, float&, float&, float&, float&)’

    So you will have to add it explicitly, eg:

    struct ConfigurableShaderParameter
    {
        std::string variableName;
        std::string description;
        float defaultValue;
        float min;
        float max;
        float step;
        float value;
    
        ConfigurableShaderParameter(
            std::string a_variableName,
            std::string a_description,
            float a_defaultValue,
            float a_min,
            float a_max,
            float a_step,
            float a_value)
        : variableName(a_variableName),
          description(a_description),
          defaultValue(a_defaultValue),
          min(a_min),
          max(a_max),
          step(a_step),
          value(a_value)
        {}
    };
    

    https://onlinegdb.com/1N4LVuYCQ

    Login or Signup to reply.
  2. At issue here is that until C++20, when initializing an aggregate you have to use {} for the initializer like

    foo bar{baz};
    

    In C++20 that rule was updated to allow () to work with aggregates. This was introduced via P0960R3 but it has not yet been included in apple-clang which is why you are getting the error only with that compiler.

    To work around this you can give ConfigurableShaderParameter a proper constructor like

    struct ConfigurableShaderParameter
    {
        ConfigurableShaderParameter(std::string variableName, std::string description, float defaultValue, float min, float max, float step, float value)
           : variableName(variableName), description(description), defaultValue(defaultValue), min(min), max(max), value(value) {}
        std::string variableName;
        std::string description;
        float defaultValue;
        float min;
        float max;
        float step;
        float value;
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search