我正在开发一个使用两个不同库的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) 首先,这个问题纯粹是理论性的。我不是在寻找解决方案(我已经知道了),我只是在寻找解释。
以下代码无法编译:
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) 我真的不知道在标题中写什么,但基本上我只有一个.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) 我明白为什么如果没有使用名称空间,以下将是一个问题.这个电话确实很模糊.我想"使用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) 由于找不到比较运算符,因此以下代码无法编译。
#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) 考虑以下示例:
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使用显式模板参数进行调用?
我有一个或多或少带有自定义键类型(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>)没有任何效果,错误不断出现。为什么它会出现,我需要更改什么才能使其正常工作?
对于一个家庭作业,我试图创建自己的版本std::find,std::begin,std::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++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,我想知道这是否是一个“功能”。这背后的理由是什么?除此之外还有对全局命名空间的更多污染吗?
我在使用名称空间时遇到歧义问题。
代码:
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)