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

如何在同一作用域无歧义地使用两个同名用户定义字面量(UDL)?

如何在同一作用域无歧义使用同名用户定义字面量(UDL)

先看这段代码:两个命名空间里定义了同名的UDL后缀_x,分别返回不同的自定义类型:

namespace foo {
    struct x{ unsigned long long i; };
    namespace literals {
        constexpr foo::x operator""_x(unsigned long long i) { return { i }; }
    }
}

namespace bar {
    struct x{ unsigned long long i; };
    namespace literals {
        constexpr bar::x operator""_x(unsigned long long i) { return { i }; }
    }
}

有没有办法在同一作用域里无歧义地用这两个UDL?普通类型或函数可以直接用全限定名解决,比如:

std::vector<std::pair<foo::x, bar::x>> v = {
     { foo::x{ 3 }, bar::x{ 14 } }, 
};

但UDL不行——除非把它当普通函数调用foo::literals::operator""_x(3),但这样就失去了UDL简写的意义。试了命名空间别名也没用,比如这种写法是错误的:

namespace f = foo::literals;
namespace b = bar::literals;

std::vector<std::pair<foo::x, bar::x>> v = {
     { 3f::_x, 14b::_x }, 
};

目前我会用辅助函数或立即调用函数表达式(IIFE)来构造容器,不过想知道有没有办法不放弃UDL的简写形式。


可行解决方案

1. 给UDL定义不同的后缀别名(最推荐)

直接给两个UDL封装新的、不同后缀的字面量运算符,完全保留简写风格:

// 给foo的_x定义别名_foo_x
constexpr foo::x operator""_foo_x(unsigned long long i) {
    return foo::literals::operator""_x(i);
}

// 给bar的_x定义别名_bar_x
constexpr bar::x operator""_bar_x(unsigned long long i) {
    return bar::literals::operator""_x(i);
}

// 使用时完全符合UDL的简写习惯
std::vector<std::pair<foo::x, bar::x>> v = {
    {3_foo_x, 14_bar_x},
    {2_foo_x, 7_bar_x}
};

这种方法可读性强,完全消除歧义,且不需要额外作用域处理,适合频繁使用的场景。

2. 利用局部作用域的using声明

如果只是偶尔使用,可以在小作用域内单独引入对应命名空间的literals,比如用lambda创建局部作用域:

std::vector<std::pair<foo::x, bar::x>> v = {
    // 第一个元素:只引入foo的literals,用3_x
    []{
        using namespace foo::literals;
        return std::pair{3_x, bar::x{14}};
    }(),
    // 第二个元素:只引入bar的literals,用14_x
    []{
        using namespace bar::literals;
        return std::pair{foo::x{3}, 14_x};
    }()
};

这种方法不需要额外定义函数,适合零散使用的场景,只是写法稍显繁琐。

3. 显式类型转换配合局部using(简化版)

如果只需要在一行里混用,也可以用花括号创建临时作用域:

std::vector<std::pair<foo::x, bar::x>> v = {
    {
        []{ using namespace foo::literals; return 3_x; }(),
        []{ using namespace bar::literals; return 14_x; }()
    },
    {
        []{ using namespace foo::literals; return 5_x; }(),
        []{ using namespace bar::literals; return 9_x; }()
    }
};

内容的提问来源于stack exchange,提问作者Dominik Kaszewski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:09:55