Question Edited
Hello I am new to c++ code . just getting my toes wet. I am learning C++. I picked OBS Studio because it is the coolest C++ i can find. i got the cmake to configure and generate 55 Microsoft visual studio community edition running on Windows 11
The project that is actually thorwing the error is
A Plugin that integrates the AMD AMF encoder into OBS Studio
I have since learn enough C plus plus to understand how to ask the question clear enough i guess.What i found out
The Error is
Error C2039 ‘<‘: is not a member of ‘Plugin::API’ enc-amf-test
The part of the code throw the error is adapter pattern doing c++ operator overload .
The implementation code can not refer the declaration code in the header file as it will require full namespace paths
My Question
My thought is the operator which is already declared in the header file. why i am get the above error message yet have this error as Error C2593 ‘operator <‘ is ambiguous
api-base.hpp
/*
* A Plugin that integrates the AMD AMF encoder into OBS Studio
* Copyright (C) 2016 - 2018 Michael Fabian Dirks
*
*/
#pragma once
#include <map>
#include <memory>
#include <string.h>
#include <vector>
#include "plugin.hpp"
namespace Plugin {
namespace API {
enum class Type : uint8_t {
Host,
Direct3D9,
Direct3D11,
OpenGL,
};
// An Adapter on an API
struct Adapter {
int32_t idLow, idHigh;
std::string Name;
Adapter() : idLow(0), idHigh(0), Name("Invalid Device") {}
Adapter(const int32_t p_idLow, const int32_t p_idHigh, const std::string& p_Name)
: idLow(p_idLow), idHigh(p_idHigh), Name(p_Name){}
Adapter(Adapter const& o) : Name(o.Name), idLow(o.idLow), idHigh(o.idHigh) {}
void operator=(Adapter const& o)
{
idLow = o.idLow;
idHigh = o.idHigh;
Name = o.Name;
}
friend bool operator <(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right);
friend bool operator >(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right);
friend bool operator <=(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right);
friend bool operator >=(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right);
friend bool operator ==(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right);
friend bool operator !=(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right);
};
// Instance of an API Adapter
struct Instance {
public:
Instance();
virtual ~Instance();
virtual Adapter GetAdapter() = 0;
virtual void* GetContext() = 0;
};
// API Interface
class IAPI {
public:
IAPI();
virtual ~IAPI();
virtual std::string GetName() = 0;
virtual Type GetType() = 0;
virtual std::vector<Adapter> EnumerateAdapters() = 0;
Adapter GetAdapterById(const int32_t idLow, const int32_t idHigh);
Adapter GetAdapterByName(const std::string& name);
virtual std::shared_ptr<Instance> CreateInstance(Adapter adapter) = 0;
};
// Static API Stuff
void InitializeAPIs();
void FinalizeAPIs();
size_t CountAPIs();
std::string GetAPIName(size_t index);
std::shared_ptr<IAPI> GetAPI(size_t index);
std::shared_ptr<IAPI> GetAPI(const std::string& name);
std::shared_ptr<IAPI> GetAPI(Type type);
std::vector<std::shared_ptr<IAPI>> EnumerateAPIs();
std::vector<std::string> EnumerateAPINames();
} // namespace API
} // namespace Plugin
api-base.cpp
#include "api-base.hpp"
#include <cinttypes>
#include "api-d3d11.hpp"
#include "api-d3d9.hpp"
#include "api-host.hpp"
#include "api-opengl.hpp"
#if defined(_WIN32) || defined(_WIN64)
extern "C" {
#include <VersionHelpers.h>
#include <windows.h>
}
#endif
using namespace Plugin::API;
// An Adapter on an API
bool Plugin::API::operator< (const Plugin::API::Adapter& left, const Plugin::API::Adapter& right)
{
if (left == right)
return left.Name < right.Name;
else
return (((uint64_t)left.idLow + ((uint64_t)left.idHigh << 32))
< ((uint64_t)right.idLow + ((uint64_t)right.idHigh << 32)));
}
bool Plugin::API::operator >(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right)
{
return right < left;
}
bool Plugin::API::operator<=(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right)
{
return !(right < left);
}
bool Plugin::API::operator >=(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right)
{
return !(left < right);
}
bool Plugin::API::operator==(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right)
{
return ((left.idLow == right.idLow) && (right.idHigh == right.idHigh));
}
bool Plugin::API::operator !=(const Plugin::API::Adapter& left, const Plugin::API::Adapter& right)
{
return !(left == right);
}
// Instance of an API Adapter
Plugin::API::Instance::Instance() {}
Plugin::API::Instance::~Instance() {}
// API Interface
Plugin::API::IAPI::IAPI() {}
Plugin::API::IAPI::~IAPI() {}
Plugin::API::Adapter Plugin::API::IAPI::GetAdapterById(const int32_t idLow, const int32_t idHigh)
{
for (auto adapter : EnumerateAdapters()) {
if ((adapter.idLow == idLow) && (adapter.idHigh == idHigh))
return adapter;
}
return *(EnumerateAdapters().begin());
}
Plugin::API::Adapter Plugin::API::IAPI::GetAdapterByName(const std::string& name)
{
for (auto adapter : EnumerateAdapters()) {
if (adapter.Name == name)
return adapter;
}
return *(EnumerateAdapters().begin());
}
// Static API Stuff
static std::vector<std::shared_ptr<IAPI>> s_APIInstances;
void Plugin::API::InitializeAPIs()
{
#ifdef _WIN32
if (IsWindows8OrGreater()) {
// DirectX 11
try {
s_APIInstances.insert(s_APIInstances.end(), std::make_shared<Direct3D11>());
} catch (const std::exception& PLOG_VAR(ex)) {
PLOG_WARNING("Direct3D 11 is not supported due to error: %s", ex.what());
} catch (...) {
PLOG_WARNING("Direct3D 11 not supported.");
}
} else if (IsWindowsXPOrGreater()) {
// Direct3D 9
try {
s_APIInstances.insert(s_APIInstances.end(), std::make_shared<Direct3D9>());
} catch (const std::exception& PLOG_VAR(ex)) {
PLOG_WARNING("Direct3D 9 is not supported due to error: %s", ex.what());
} catch (...) {
PLOG_WARNING("Direct3D 9 not supported.");
}
}
#endif
// Mikhail says these are for compatibility only, not actually backends.
//// OpenGL
//{
// s_APIInstances.insert(s_APIInstances.end(), std::make_shared<OpenGL>());
//}
//// Host
//{
// s_APIInstances.insert(s_APIInstances.end(), std::make_shared<Host>());
//}
}
void Plugin::API::FinalizeAPIs()
{
s_APIInstances.clear();
}
size_t Plugin::API::CountAPIs()
{
return s_APIInstances.size();
}
std::string Plugin::API::GetAPIName(size_t index)
{
if (index >= s_APIInstances.size())
throw std::exception("Invalid API Index");
return s_APIInstances[index].get()->GetName();
}
std::shared_ptr<IAPI> Plugin::API::GetAPI(size_t index)
{
if (index >= s_APIInstances.size())
throw std::exception("Invalid API Index");
return s_APIInstances[index];
}
std::shared_ptr<IAPI> Plugin::API::GetAPI(const std::string& name)
{
for (auto api : s_APIInstances) {
if (name == api->GetName()) {
return api;
}
}
// If none was found, return the first one.
return *s_APIInstances.begin();
}
std::shared_ptr<IAPI> Plugin::API::GetAPI(Type type)
{
for (auto api : s_APIInstances) {
if (type == api->GetType()) {
return api;
}
}
// If none was found, return the first one.
return *s_APIInstances.begin();
}
std::vector<std::shared_ptr<IAPI>> Plugin::API::EnumerateAPIs()
{
return std::vector<std::shared_ptr<IAPI>>(s_APIInstances);
}
std::vector<std::string> Plugin::API::EnumerateAPINames()
{
std::vector<std::string> names;
for (auto api : s_APIInstances) {
names.push_back(api->GetName());
}
return names;
}
When I build these code in Visual Studio 2022 Community Version with clang Format on as if you look at the photo on the right the source of error say CL.
I get error
Error C2039 ‘<‘: is not a member of ‘Plugin::API’
![Text](https://stackoverflow.com/image.jpg)
Please Help Me
ok i am really to build OBS Studio from source
you find the code in this link
https://github.com/obsproject/obs-amd-encoder/blob/master/source/api-base.cpp
2
Answers
Unqualified friend declarations declare the friends in the global namespace, not in the namespace of the enclosing class.
You need to declare them as friends with the fully qualified names.’
That is, not
operator<
butPlugin::API::operator<
, just like when you define them.should be
and it shouldn’t be declared as
friend
in thestruct Adaptor
declaration.Like this