败犬日报 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++;
事实上这个没有定论,标准没有明确说明是什么行为。
当然,这种写法必然是不推荐的。