Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用常量/非常量指针/引用参数模板函数_C++_C++11_C++14_C++17 - Fatal编程技术网

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
    /
    QByteArray
    (或您可以添加的任何其他类型)的(const)引用将永远不会与此模板匹配,并且使用
    std::conditional
    std::is_const>的组合从
    T
    中推断出常量

  • 第二个模板函数将匹配具有成员函数
    data()
    (这是
    std::vector
    (自C++11以来)和
    QByteArray
    )的任何类型
    T
    ),并且由于
    T::data
    具有常量重载,因此推导出常量

在第二个函数中使用尾部返回类型将允许您为不提供
.data()
方法的类型添加额外的重载,而不会产生歧义