【发布时间】:2021-04-04 20:48:02
【问题描述】:
我想实现一个函数模板,它接受两个参数,一个 T* 和一个 T,但第二个参数的类型由第一个参数决定。这是一个最小的非工作示例:
#include <cstddef>
#include <cstring>
#include <cstdint>
#include <type_traits>
#include <vector>
template<typename T> void
patch(T *dst, T src)
{
static_assert(std::is_standard_layout_v<T>);
std::byte *p = reinterpret_cast<std::byte *>(&src);
std::vector newval(p, p + sizeof(src));
// In the real code, memcpy happens later if a transaciton commits
std::memcpy(dst, newval.data(), newval.size());
}
int
main()
{
std::uint16_t u16;
patch(&u16, 0); // Fails to compile because 0 is int, not uint16_t
}
不幸的是,这段代码无法编译,因为无法在 patch(&u16, 0) 中推断要修补的类型 T,因为 0 是 int 而不是 std::uint16_t。显然我可以投 0 或致电 patch<uint16_t>(...),但在理想情况下我不必这样做。
另一方面,如果第二个参数涉及某种非平凡的类型计算,我可以解决这个问题。例如,如果我将函数声明为:
template<typename T> void
patch(T *dst, std::decay_t<T> src) {/*...*/}
当我最初提出这个问题时,我实施了以下操作并认为它不起作用。但是,我一定犯了一个错误,因为正如所选答案所指出的那样,它确实有效:
template<typename T> struct sametype {
using type = T;
};
template<typename T> using sametype_t = typename sametype<T>::type;
template<typename T> void
patch(T *dst, sametype_t<T> src) {/*...*/}
我的问题是可以对模板函数参数应用的最小转换是什么,以强制其类型由同一函数的不同参数的类型推断?
【问题讨论】:
标签: c++ templates c++17 function-templates