c++ - 在解决编译器错误 C2678 时遇到问题

标签 c++ compiler-errors visual-studio-2017 c++17 operator-keyword

这是我的代码:

Register.h

#include <assert.h>
#include <bitset>
#include <cstdint>
#include <iostream>
#include <iomanip>
#include <iterator>
#include <limits>
#include <numeric>

namespace vpc {

    using u8  = std::uint8_t;
    using u16 = std::uint16_t;
    using u32 = std::uint32_t;
    using u64 = std::uint64_t;

    template<typename T>
    struct Register {
        T data;
        T value;
        std::bitset<sizeof(T)* CHAR_BIT> bits;

        Register() = default;

        template<typename P>
        explicit Register(const P val) :
            data{ static_cast<T>(val) },
            value{ data },
            bits{ data }
        {}

        template<typename P>
        Register(const P val, const u8 idx) :
            data{ static_cast<T>((val >> std::size(bits) * idx) &
                  std::numeric_limits<std::make_unsigned<T>>::max()) },
            value{ data },
            bits{ data }
        {
            assert(idx >= '\0' && idx < sizeof(T));
        }

        template<typename P>
        Register(const Register<P>& reg) :
            data{ static_cast<T>(reg.data) },
            value{ data },
            bits{ data }
        {}

        template<typename P>
        Register(const Register<P>& reg, const u8 idx) :
            data{ static_cast<T>((reg.data >> std::size(bits) * idx) &
                  std::numeric_limits<std::make_unsigned<T>>::max()) },
            value{ data },
            bits{ data }
        {
            assert(idx >= 0 && idx < sizeof(T));
        }

    };

    template<typename T>
    std::ostream& operator<<(std::ostream& os, const Register<T>& r) {
        return os << "Reg" << std::size(r.bits) << '(' << +r.data << ")\nhex: 0x"
            << std::uppercase << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex
            << +r.data << std::dec << "\nbin: "
            << r.bits << "\n\n";
    }

    using Reg8 =  Register<u8>;
    using Reg16 = Register<u16>;
    using Reg32 = Register<u32>;
    using Reg64 = Register<u64>;

} // namespace vpc

在我使用此类的主函数中,默认构造函数起作用,第二个构造函数起作用 通过传入值和变量。第三个构造函数给我一个编译器错误。

main.cpp

#include "Register.h"

int main() {
    using namespace vpc;

    u16 val = 0xC97B;

    Reg8 r8low( val, 0 );  // should be 7B
    Reg8 r8high( val, 1 ); // should be C9

    std::cout << r8low << r8high;

    return EXIT_SUCCESS;
}

这是我从 Visual Studio 2017 得到的编译器错误:

1>------ Build started: Project: TestRegister, Configuration: Debug x64 ------
1>main.cpp
1>c:\***\register.h(38): error C2678: binary '&': no operator found which takes a left-hand operand of type 'int' (or there is no acceptable conversion)
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\cstddef(45): note: could be 'std::byte std::operator &(const std::byte,const std::byte) noexcept' [found using argument-dependent lookup]
1>c:\***\register.h(39): note: while trying to match the argument list '(int, _Ty)'
1>        with
1>        [
1>            _Ty=std::make_unsigned<vpc::u8>
1>        ]
1>c:\***\main.cpp(15): note: see reference to function template instantiation 'vpc::Register<vpc::u8>::Register<vpc::u16>(const P,const vpc::u8)' being compiled
1>        with
1>        [
1>            P=vpc::u16
1>        ]
1>c:\***\main.cpp(15): note: see reference to function template instantiation 'vpc::Register<vpc::u8>::Register<vpc::u16>(const P,const vpc::u8)' being compiled
1>        with
1>        [
1>            P=vpc::u16
1>        ]
1>Done building project "TestRegister.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我明白编译器错误是什么;但我不知道到底是什么原因造成的。是否来自 std::sizestd::numeric_limits<...>() ?它确实说左手边,所以我假设 std::size() ...

我不知道如何解决这个问题。我该怎么做才能编译这个?我几乎可以肯定如果这个构造函数导致了这个错误,那么我的最后一个构造函数可能会导致相同或相似的错误。

最佳答案

更改 std::make_unsigned<T>std::make_unsigned_t<T> (或 C++14 之前的 typename std::make_unsigned<T>::type);您需要相应的无符号类型,而不是 std::make_unsigned 本身。即

template<typename P>
Register(const P val, const u8 idx) :
    data{ static_cast<T>((val >> std::size(bits) * idx) &
          std::numeric_limits<std::make_unsigned_t<T>>::max()) },
//                                              ^^
    value{ data },
    bits{ data }
{
    assert(idx >= '\0' && idx < sizeof(T));
}

关于c++ - 在解决编译器错误 C2678 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56141075/

相关文章:

c++ - 无法调试共享库 - 符号未正确加载

c++ - 在 Cassandra 中插入多列

c++ - 有没有人有使用 pc-lint 的好技巧?

java - 删除了 Switch 语句以解决错误,但错误仍然存​​在。

c++ - 项目构建失败: "gcroot.h This document is opened by another project"

c++ - 在 C++ 中使用 startMATLAB 并在 r2017b 中使用 "MatlabEngine.hpp"时发出问题

c++ - std::array 实例化错误

c++ - '未在此范围内声明'C++

mfc - VS 2017 : fatal error RC1015: cannot open include file 'winres.h'

c++ - 由于某些原因,for循环中的数组不起作用