macOS编译报错:向std::vector添加struct时无匹配构造函数
emplace_back无法构造自定义struct 问题场景
在跨平台C++20项目中,使用emplace_back向std::vector添加自定义struct的代码如下:
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);
项目通过CMake设置C++20标准:
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON)
该代码在Ubuntu和Windows编译正常,但在GitHub Actions的macOS-latest环境(Xcode 14.2)编译失败,报错如下:
/Users/runner/work/epoch/epoch/src/frontend/src/ConfigurableShader.cpp:41:30: note: in instantiation of function template specialization 'std::vectorepoch::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. 给自定义struct添加显式构造函数
Clang(Xcode默认编译器)对C++20聚合类型的构造规则执行更严格,需要显式构造函数匹配emplace_back的参数列表:
struct ConfigurableShaderParameter { std::string variableName; std::string description; float defaultValue; float min; float max; float step; float value; // 匹配参数列表的构造函数 ConfigurableShaderParameter(std::string varName, std::string desc, float defaultVal, float minVal, float maxVal, float stepVal, float val) : variableName(std::move(varName)), description(std::move(desc)), defaultValue(defaultVal), min(minVal), max(maxVal), step(stepVal), value(val) {} };
2. 改用聚合初始化语法配合emplace_back
如果不想添加构造函数,可以直接传入初始化列表触发聚合初始化,兼容Clang的要求:
// 方式1:直接传递聚合初始化对象 parameters.emplace_back( ConfigurableShaderParameter{variableName, description, defaultValue, min, max, step, defaultValue} ); // 方式2:更简洁的push_back写法(C++17+支持) parameters.push_back( {variableName, description, defaultValue, min, max, step, defaultValue} );
3. 升级Xcode版本(可选)
Xcode 14.2的Clang对C++20聚合初始化支持存在滞后,切换到更高版本(如Xcode 15.x)可改善兼容性。在GitHub Actions中可通过以下步骤设置:
jobs: build: runs-on: macos-latest steps: - name: Select Xcode 15.2 run: sudo xcode-select -s /Applications/Xcode_15.2.app/Contents/Developer
内容的提问来源于stack exchange,提问作者aghidini

