相关疑难解决方法(0)

一个库中的函数与另一个库中的模板匹配

我正在开发一个使用两个不同库的C++项目:spdlog用于日志记录,mutils-serialization用于将对象序列化为字节(用于通过网络发送).两个库都正确使用命名空间,但是当我尝试编写同时使用它们的程序时,我的编译器(g ++ 6.2)给了我无意义的错误,这些错误似乎表明它试图从spdlog库中实例化一个函数模板通过使用mutils库中的函数模板的定义.

这是我的简单测试程序:

#include <spdlog/spdlog.h>
#include <spdlog/fmt/ostr.h>
#include "TestSerializableObject.h"

int main(int argc, char** argv) {
    auto global_logger = spdlog::rotating_logger_mt("global_logger", "log", 1024 * 1024 * 500, 3);
    global_logger->set_pattern("[%H:%M:%S.%e] [%l] %v");
    global_logger->set_level(spdlog::level::trace);

    std::shared_ptr<spdlog::logger> logger(spdlog::get("global_logger"));

    auto message = std::make_shared<messaging::TestSerializableObject>(
        1, 2, "A message!");

    logger->trace("Received a message: {}", *message);
}
Run Code Online (Sandbox Code Playgroud)

TestSerializableObject是一个实现的简单类mutils::ByteRepresentable(启用序列化和拉入mutils-serialization库的接口),并提供operator<<(spdlog能够记录它所需的).如有必要,我可以发布代码.

当我编译它时g++ -std=c++14 -I"./src" -I"./libraries" -I"./libraries/mutils/" -L"./libraries/" -O0 -g3 -Wall "src/LibraryCollisionTest.cpp",我得到了这个冗长,丑陋的错误(别担心,我会帮你解析它):

In file included from ./libraries/mutils/mutils.hpp:3:0,
                 from ./libraries/mutils-serialization/SerializationSupport.hpp:2,
                 from src/TestSerializableObject.h:10, …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++14 spdlog

6
推荐指数
1
解决办法
453
查看次数

C++ 奇怪的对重载函数的不明确调用

首先,这个问题纯粹是理论性的。我不是在寻找解决方案(我已经知道了),我只是在寻找解释。

以下代码无法编译:

struct foo {};
void a(foo) {}
namespace foobar {
    void a(foo) {}
    void b(foo f) {a(f);}
}
int main() {return 1;}
Run Code Online (Sandbox Code Playgroud)

MSVC++:

1>c:\projects\codetests\main.cpp(7) : error C2668: 'foobar::a' : ambiguous call to overloaded function
1>        c:\projects\codetests\main.cpp(4): could be 'void foobar::a(foo)'
1>        c:\projects\codetests\main.cpp(2): or       'void a(foo)' [found using argument-dependent lookup]
1>        while trying to match the argument list '(foo)'
Run Code Online (Sandbox Code Playgroud)

G++:

main.cpp: In function 'void foobar::b(foo)':
main.cpp:5:20: error: call of overloaded 'a(foo&)' is ambiguous
main.cpp:5:20: note: candidates are:
main.cpp:4:7: note: void …
Run Code Online (Sandbox Code Playgroud)

c++ namespaces compiler-theory ambiguous

5
推荐指数
1
解决办法
3035
查看次数

Visual Studio警告有关函数不在全局命名空间中

我真的不知道在标题中写什么,但基本上我只有一个.cpp,只包含标准库头,没有"使用"关键字.我制作了自己的"生成(...)"功能.包含库之后,Visual Studio向我显示一个错误(函数被调用的地方),基本上说它不知道是选择std :: generate(...)还是生成(...)因为它们有匹配参数列表.

这是一个错误还是我错过了什么?我还可以补充说我正在使用VS2015.

#include <iostream>
#include <ctime>
#include <vector>
#include <algorithm>

template<typename Iter, typename Function>
Function generate(Iter begin, Iter end, Function f)
{
    while (begin != end)
    {
        *begin = f();
        ++begin;
    }
    return f;
}

class Random
{
public:
    Random(int low, int high)
        : mLow(low), mHigh(high)
    {}

    int operator()()
    {
        return mLow + rand() % (mHigh - mLow + 1);
    }

private:
    int mLow;
    int mHigh;
};

class Print
{
    void operator()(int t)
    {
        std::cout << t …
Run Code Online (Sandbox Code Playgroud)

c++ visual-studio-2015

5
推荐指数
1
解决办法
460
查看次数

虽然不同的命名空间,但重载函数的调用是模糊的

我明白为什么如果没有使用名称空间,以下将是一个问题.这个电话确实很模糊.我想"使用stD :: swap;" 将定义使用哪种方法.

为什么它适用于"int"而不是"class"?

    #include <memory>

    namespace TEST {

    class Dummy{};

    void swap(Dummy a){};
    void sw(int x){};

    }

    namespace stD {

    void swap(TEST::Dummy a){};
    void sw(int x){};

    class aClass{
    public:
        void F()
        {
            using stD::swap;
            TEST::Dummy x;
            swap(x);
        }

        void I()
        {
            using stD::sw;
            int b = 0;
            sw(b);
        }
    };

    }
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

    ../src/Test.h: In member function ‘void stD::aClass::F()’:
    ../src/Test.h:26:9: error: call of overloaded ‘swap(TEST::Dummy&)’ is ambiguous
       swap(x);
             ^
    ../src/Test.h:26:9: note: candidates are:
    ../src/Test.h:17:6: note: void stD::swap(TEST::Dummy)
     void swap(TEST::Dummy …
Run Code Online (Sandbox Code Playgroud)

c++ ambiguous

4
推荐指数
1
解决办法
471
查看次数

在命名空间中使用自己的类比较std :: vector不会编译

由于找不到比较运算符,因此以下代码无法编译。

#include <vector>
#include <iostream>
#include <string>

namespace Cool {
    struct Person {
        std::string name;
    };
}

bool operator==(const Cool::Person&  p1, const Cool::Person& p2) {
    return p1.name == p2.name;
}

int main(int, char *[])
{
    std::vector<Cool::Person> a{ {"test"} };
    std::vector<Cool::Person> b{ {"test"} };
    bool ok = a == b;
    std::cout << ok << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

经过一些实验,我发现以下代码可以完美编译:

#include <vector>
#include <iostream>
#include <string>

namespace Cool {
    struct Person {
        std::string name;
    };

    bool operator==(const Person&  p1, const Person& p2) {
        return …
Run Code Online (Sandbox Code Playgroud)

c++ stl namespaces operator-overloading stdvector

4
推荐指数
1
解决办法
108
查看次数

为什么我不能使用显式模板参数调用模板友元函数?

考虑以下示例:

struct S {
    template<typename T = void>
    friend void foo(S) {
    }
};

int main() {
    S s;
    foo(s); // (1)
    foo<void>(s); // (2)
}
Run Code Online (Sandbox Code Playgroud)

我的 GCC 9.2.0 无法编译(2)并出现以下错误:

a.cpp: In function 'int main()':
a.cpp:10:5: error: 'foo' was not declared in this scope
   10 |     foo<void>(s);
      |     ^~~
a.cpp:10:9: error: expected primary-expression before 'void'
   10 |     foo<void>(s);
      |         ^~~~
Run Code Online (Sandbox Code Playgroud)

不过,(1)效果很好。为什么是这样?如何foo使用显式模板参数进行调用?

c++ templates friend friend-function

4
推荐指数
1
解决办法
8088
查看次数

std::map 不接受我的运算符&lt;

我有一个或多或少带有自定义键类型(Point2ffrom OpenCV)的地图,因此需要编写我自己的operator<. 除了,我的operator<没有被接受。

通过键创建地图/访问元素:

using namespace cv;
void foo()
{
    map<Point2f, double> properties;

    properties[Point2f(0, 0)] = 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我的运营商:

using namespace cv;
bool operator<(Point2f lhs, Point2f rhs)
{
    return lhs.x == rhs.x ? lhs.y < rhs.y : lhs.x < rhs.x;
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用上面的键设置地图的值时,我的编译器给了我

/usr/include/c++/4.8/bits/stl_function.h|235|error: no match for ‘operator<’ (operand types are ‘const cv::Point_<float>’ and ‘const cv::Point_<float>’)|
Run Code Online (Sandbox Code Playgroud)

(gcc, IDE 代码::块)

我已经试过了

  • 准确指定类型 ( cv::Point_<float>)
  • 将运算符直接放在调用它的函数上方
  • 对传递给运算符的变量使用常量、引用或常量引用而不是值

没有任何效果,错误不断出现。为什么它会出现,我需要更改什么才能使其正常工作?

c++ opencv c++11

3
推荐指数
1
解决办法
454
查看次数

对于某些函数,“无法将 'T [S]' 与 'std::vector&lt;int&gt;' 匹配”,但不能匹配其他具有相同参数列表的函数

对于一个家庭作业,我试图创建自己的版本std::findstd::beginstd::end,和std::size

我写了一些看起来像这样的代码:

#include <vector>

template <typename I, typename T>
I find(const I& beg, const I& end, const T& sought)
    {/* ... */}

template <typename T, size_t S>
T* begin(T (&a)[S])
    {return &a;}

template <typename T, size_t S>
T* end(T (&a)[S])
    {return &a + S;}

template <typename T, size_t S>
constexpr size_t size(T (&)[S])
    {return S;}

int main()
{
    std::vector<int> vec = {0, 1, 2, 3};

    // ...

    // test not-found case (and …
Run Code Online (Sandbox Code Playgroud)

c++ templates types

3
推荐指数
1
解决办法
68
查看次数

在 C++20 中,&lt;tuple&gt; 内的 get&lt;&gt;() 函数不再位于命名空间 std 中。为什么?

以下代码不能在 C++17 中编译,而是在 C++20 中编译:

#include <tuple>

int main() {

    auto t = std::make_tuple(1, 2);
    get<0>(t); // no std:: required!

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

由于这适用于 g++ 和 clang++ 以及两者-stdlib=libc++-stdlib=libstdc++甚至在 msvc 中/std:c++20,我想知道这是否是一个“功能”。这背后的理由是什么?除此之外还有对全局命名空间的更多污染吗?

c++ get global-namespace c++20

3
推荐指数
1
解决办法
110
查看次数

使用命名空间时的歧义:“using”单一事物会泄漏其他东西吗?

我在使用名称空间时遇到歧义问题。

代码:

namespace app::hal {
    enum class Motor {
        Left  = 0,
        Right = 1
    };

    void setMotor(Motor which, float duty);
}

namespace app::control {
    using Motor = app::hal::Motor;

    void setMotor(Motor which, float duty);
    float getMotor(Motor which);

}

inline void test() {
    using app::control::setMotor;
    using app::control::Motor;
    setMotor(Motor::Left, 0);
}
Run Code Online (Sandbox Code Playgroud)

错误:

<source>:24:17: error: call of overloaded 'setMotor(app::hal::Motor, int)' is ambiguous
   24 |         setMotor(Motor::Left, 0);
      |         ~~~~~~~~^~~~~~~~~~~~~~~~
<source>:15:14: note: candidate: 'void app::control::setMotor(Motor, float)'
   15 |         void setMotor(Motor which, float duty);
      |              ^~~~~~~~ …
Run Code Online (Sandbox Code Playgroud)

c++ namespaces using-declaration

3
推荐指数
1
解决办法
101
查看次数