explicit specialization breakage/regression?
attempting to build obs-multi-rtmp with cmake 3.22.1 seems to fail due to "explicit specialization". I'm not sure if this applies the same way or not, but it appears its supposed to be allowed according to this and this
~/Downloads/obs-multi-rtmp-0.2.8 $ cmake -DCMAKE_INSTALL_PREFIX="/usr" -DOBS_SRC_DIR="/usr/include/obs" -B build .
-- The C compiler identification is GNU 11.1.0
-- The CXX compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/build
~/Downloads/obs-multi-rtmp-0.2.8 $ cmake --build build --config Release
[ 20%] Building CXX object CMakeFiles/obs-multi-rtmp.dir/cmake_pch.hxx.gch
In file included from /home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/build/CMakeFiles/obs-multi-rtmp.dir/cmake_pch.hxx:5,
from <command-line>:
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:46:14: error: explicit specialization in non-namespace scope ‘struct QJsonUtil’
46 | template<>
| ^
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:47:12: error: too few template-parameter-lists
47 | struct JsonType<double> {
| ^~~~~~~~~~~~~~~~
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:52:14: error: explicit specialization in non-namespace scope ‘struct QJsonUtil’
52 | template<>
| ^
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:53:12: error: too few template-parameter-lists
53 | struct JsonType<int> {
| ^~~~~~~~~~~~~
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:58:14: error: explicit specialization in non-namespace scope ‘struct QJsonUtil’
58 | template<>
| ^
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:59:12: error: too few template-parameter-lists
59 | struct JsonType<QString> {
| ^~~~~~~~~~~~~~~~~
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:64:14: error: explicit specialization in non-namespace scope ‘struct QJsonUtil’
64 | template<>
| ^
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:65:12: error: too few template-parameter-lists
65 | struct JsonType<std::string> {
| ^~~~~~~~~~~~~~~~~~~~~
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:70:14: error: explicit specialization in non-namespace scope ‘struct QJsonUtil’
70 | template<>
| ^
/home/jcfrosty/Downloads/obs-multi-rtmp-0.2.8/src/pch.h:71:12: error: too few template-parameter-lists
71 | struct JsonType<bool> {
| ^~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/obs-multi-rtmp.dir/build.make:77: CMakeFiles/obs-multi-rtmp.dir/cmake_pch.hxx.gch] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/obs-multi-rtmp.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
The file in question is the pch.h file in the src folder and looks like this:
#pragma once
#include <memory>
#include <string>
#include <optional>
#include <type_traits>
#include <QMainWindow>
#include <QDockWidget>
#include <QWidget>
#include <QLabel>
#include <QString>
#include <QPushButton>
#include <QScrollArea>
#include <QGridLayout>
#include <QEvent>
#include <QThread>
#include <QLineEdit>
#include <QTimer>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QMessageBox>
#include <QComboBox>
#include <QCheckBox>
#include <QGroupBox>
#include <QAction>
#include "obs-multi-rtmp.h"
#include "obs-module.h"
#include "obs-frontend-api.h"
#include "util/config-file.h"
inline std::string tostdu8(const QString& qs)
{
auto b = qs.toUtf8();
return std::string(b.begin(), b.end());
}
struct QJsonUtil {
using JsonIt = QJsonObject::iterator;
template<class T>
struct JsonType;
template<>
struct JsonType<double> {
bool Check(JsonIt& it) { return it->isDouble(); }
double Get(JsonIt& it) { return it->toDouble(); }
};
template<>
struct JsonType<int> {
bool Check(JsonIt& it) { return it->isDouble(); }
int Get(JsonIt& it) { return static_cast<int>(std::round(it->toDouble())); }
};
template<>
struct JsonType<QString> {
bool Check(JsonIt& it) { return it->isString(); }
QString Get(JsonIt& it) { return it->toString(); }
};
template<>
struct JsonType<std::string> {
bool Check(JsonIt& it) { return it->isString(); }
std::string Get(JsonIt& it) { return tostdu8(it->toString()); }
};
template<>
struct JsonType<bool> {
bool Check(JsonIt& it) { return it->isBool(); }
bool Get(JsonIt& it) { return it->toBool(); }
};
template<class Val>
static Val Get(QJsonObject& json, const char* key, Val def) {
auto it = json.find(key);
if (it != json.end() && JsonType<Val>().Check(it))
return JsonType<Val>().Get(it);
else
return def;
}
template<class Val>
static std::optional<Val> Get(QJsonObject& json, const char* key) {
auto it = json.find(key);
if (it != json.end() && JsonType<Val>().Check(it))
return JsonType<Val>().Get(it);
else
return std::optional<Val>{};
}
template<class Fun>
static bool IfGet(QJsonObject& json, const char* key, const Fun& f) {
using Val = decltype(f({}));
auto it = json.find(key);
if (it != json.end() && JsonType<Val>().Check(it)) {
f(JsonType<Val>().Get(it));
return true;
} else {
return false;
}
}
};
Is this intended behavior or a regression?
Edited by Jerrod Frost