You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clang++下C++友元用户自定义字面量声明失败问题咨询

C++用户定义字面量友元声明问题分析

问题代码

namespace ns {
class MyClass {
private:
    int value;
    MyClass(int val) : value(val) {}

    friend MyClass operator"" _myudl(unsigned long long int val); // Friend UDL declaration

    friend MyClass (::operator"" _myudl) (unsigned long long int val); // not working too;

public:
    int getValue() const { return value; }
};
}

// Definition of the friend UDL outside the class
ns::MyClass operator"" _myudl(unsigned long long int val) {
    return ns::MyClass(static_cast<int>(val));
}

int main() {
    ns::MyClass obj = 100_myudl; // Using the friend UDL
    return 0;
}

编译报错:使用clang++ -std=c++20编译时失败,提示调用私有构造函数,说明友元声明未生效。

编译器行为正确性

Clang的行为符合C++标准,是正确的。

原因在于:类内的友元声明friend MyClass operator"" _myudl(...)默认会将该用户定义字面量(UDL)函数声明到当前类所在的ns命名空间中,但实际定义的UDL函数属于全局命名空间(返回类型是ns::MyClass不影响函数本身的命名空间归属)。这两个是完全独立的函数实体,因此类的友元关系无法作用到全局的UDL函数上,导致它无法访问私有构造函数。

部分编译器(如GCC)可能会接受这段代码,但这属于非标准扩展行为,不符合C++规范。

仅修改友元声明的修复方法

需要明确指定友元是全局命名空间下的UDL函数,将友元声明修改为:

friend MyClass ::operator"" _myudl(unsigned long long int val);

或者简化参数类型写法:

friend MyClass ::operator"" _myudl(unsigned long long);

添加::前缀后,类会明确将全局命名空间下的operator"" _myudl函数标记为友元,此时全局UDL函数就能正常访问MyClass的私有构造函数,编译即可通过。

内容的提问来源于stack exchange,提问作者Ashcoll Ash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:14:59