Skip to content

败犬日报 2024-12-27

1. 两个模板约束有交集的重载函数怎么处理

cpp
#include <concepts>
#include <cstdint>

template <typename T>
concept i64_u64 = std::same_as<T, int64_t> || std::same_as<T, uint64_t>;

template <typename T>
concept i64_i32 = std::same_as<T, int64_t> || std::same_as<T, int32_t>;

template <i64_u64 T>
void f(T x) {}

template <i64_i32 T>
void f(T x) {}

int main() { f(int64_t(0)); }

这样会报错 error: call of overloaded 'f(int64_t)' is ambiguous

一个解决方法是再实现一个交集的重载函数:

cpp
template <typename T>
concept intersection = i64_u64<T> && i64_i32<T>;

template <intersection T>
void f(T x) { std::cout << "Union\n"; }

可能更推荐的做法是只写一个函数,用 if constexpr 来处理:

cpp
template <typename T>
void f(T x)
requires(i64_u64<T> || i64_i32<T>)
{
    if constexpr (i64_u64<T>) {
        std::cout << 1 << std::endl;
    } else if constexpr (i64_i32<T>) {
        std::cout << 2 << std::endl;
    }
}

2. auto&& t = T{}; 是不是安全的

安全,这个和 const auto &t = T{}; 是一个道理,引用延长了生命周期。

https://zh.cppreference.com/w/cpp/language/lifetime 里有记载:

可以通过绑定到引用来延长临时对象的生存期,细节见引用初始化。

右值引用的本职是实现移动语义,延长生存期只是为了让表现跟 const T& 一致。

3. 修改临时变量是不是安全的

cpp
const auto& t = T{};
auto p = const_cast<T&>(t);
p.i++;

事实上这个没有定论,标准没有明确说明是什么行为。

当然,这种写法必然是不推荐的。

4. 据说有个项目从 c 重构到 zig,结果性能莫名其妙的慢了 10%