I have a VariantType
that can be empty, i.e. has a void state.
The following code, when compiling with Mingw Builds x64 5.3.0 generates the error:
error: conversion from 'void' to non-scalar type 'VariantType {aka utils::Variant<bool, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >}' requested|
How can I avoid the error:
#include <Common/Variant.hpp>
using namespace utils;
#include <vector>
#include <unordered_map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <map>
using VariantType = Variant<bool,int,std::string>;
class EFBase
{
public:
virtual ~EFBase() {}
};
template<typename FuncSig>
class EF : public EFBase
{
public:
EF(std::function<FuncSig> func) : m_function(func) {};
std::function<FuncSig> m_function;
};
class Functions
{
public:
using FuncMap = std::map<std::string,EFBase*>;
FuncMap m_functions;
template<typename FuncType>
void Add(const std::string name, FuncType function)
{
m_functions.emplace(FuncMap::value_type(name,new EF<FuncType>(std::function<FuncType>(function))));
}
template<typename... Args>
VariantType Invoke(const std::string& name, Args... args)
{
auto itr = m_functions.find(name);
if(itr == m_functions.end())
return VariantType();
typedef void Func(typename std::remove_reference<Args>::type...);
std::type_index index(typeid(Func));
const EFBase& a = *itr->second;
std::function<Func> func = static_cast<const EF<Func>&>(a).m_function;
if(typeid(typename std::function<Func>::result_type) == typeid(void))
{
func(std::forward<Args>(args)...);
return VariantType();
}
else
{
VariantType x = func(std::forward<Args>(args)...);
return x;
}
}
};
int main()
{
Functions f;
f.Add<int(bool)>("get3",[](bool x) { return 3; });
VariantType v = f.Invoke<>("get3",true);
return 0;
}
I would've thought that the check for the result_type
of the function object would have been enough; but I guess it's not because of the template instantiation. Do I need a sort of helper struct that does something different in a void case (based on template params)?
The purpose of the code is to store functions of arbitrary signature in a map by name so that they can be called upon later. The VariantType
handles the multiple possible return values.
The error is on the assignment in the else
block of the Invoke
method.
The VariantType
is a fair bit of code, so I didn't provide it (I'm not sure it's pertinent anyway). But I can if needed.
Aucun commentaire:
Enregistrer un commentaire