C++ 如何使用常量/非常量指针/引用参数模板函数
假设我有以下一组函数:C++ 如何使用常量/非常量指针/引用参数模板函数,c++,c++11,c++14,c++17,C++,C++11,C++14,C++17,假设我有以下一组函数: typedef uint8_t byte; inline byte *as_bytes(char *data) { return reinterpret_cast<byte*>(data); } inline byte *as_bytes(std::vector<byte> &v) { return &v[0]; } inline byte *as_bytes(QByteArray &a) {
typedef uint8_t byte;
inline byte *as_bytes(char *data) {
return reinterpret_cast<byte*>(data);
}
inline byte *as_bytes(std::vector<byte> &v) {
return &v[0];
}
inline byte *as_bytes(QByteArray &a) {
return as_bytes(a.data());
}
inline const byte *as_cbytes(const char *data) {
return reinterpret_cast<const byte*>(data);
}
inline const byte *as_cbytes(const std::vector<byte> &v) {
return &v[0];
}
inline const byte *as_cbytes(const QByteArray &a) {
return as_cbytes(a.data());
}
typedef uint8字节;
内联字节*作为字节(字符*数据){
返回重新解释(数据);
}
内联字节*as_字节(std::vector&v){
返回&v[0];
}
内联字节*as_字节(QByteArray&a){
返回为_字节(a.data());
}
内联常量字节*作为字节(常量字符*数据){
返回重新解释(数据);
}
内联常量字节*as_cbytes(常量std::vector&v){
返回&v[0];
}
内联常量字节*作为字节(常量QByteArray&a){
以字节形式返回(a.data());
}
问题:我可以为这些函数设置模板,以便常量和指针/引用类型推断能够正常工作吗?我希望看到的结果可能如下所示:
template<typename T>
inline byte *as_bytes(T data) {
return reinterpret_cast<byte*>(data);
}
template<>
inline byte *as_bytes(std::vector<byte> &v) {
return &v[0];
}
template<>
inline byte *as_bytes(QByteArray &a) {
return as_bytes(a.data());
}
模板
内联字节*as_字节(T数据){
返回重新解释(数据);
}
模板
内联字节*as_字节(std::vector&v){
返回&v[0];
}
模板
内联字节*as_字节(QByteArray&a){
返回为_字节(a.data());
}
当然,这段代码对我来说不起作用,原因有二:
- 我希望推导出参数的常数,并将其转发给返回类型李>
- 因为我们讨论的是函数,所以
和std::vector
的专门化不会像预期的那样工作,因为总是QByteArray
会因为函数重载而被选择模板内联字节*as_字节(t数据)
也许有一些C++11/14/17机制可以解决这些问题,并最终得到3个漂亮的函数?这可能适合您的需要:
template<typename T>
inline auto as_bytes(T *data) {
return reinterpret_cast<
typename std::conditional<std::is_const<T>{}, const byte*, byte*>::type
>(data);
}
template <typename T>
inline auto as_bytes(T &t) -> decltype(as_bytes(t.data())) {
return as_bytes(t.data());
}
模板
内联自动作为字节(T*数据){
返回重新解释<
typename std::conditional::type
>(数据);
}
模板
内联自动作为字节(T&T)->decltype(作为字节(T.data())){
返回为_字节(t.data());
}
这是如何工作的:
- 第一个模板函数采用
,因此对T*
/std::vector
(或您可以添加的任何其他类型)的(const)引用将永远不会与此模板匹配,并且使用QByteArray
和std::conditional
std::is_const>的组合从
中推断出常量T
- 第二个模板函数将匹配具有成员函数
(这是data()
(自C++11以来)和std::vector
)的任何类型QByteArray
),并且由于T
具有常量重载,因此推导出常量T::data
.data()
方法的类型添加额外的重载,而不会产生歧义