基于本文,我尝试创建一个泛型解析器,它将被调用函数的返回值作为字符串输出。
将std::string的std::vector解析为任意类型的std::tuple
不幸的是,我不知道如何格式化一个返回void的函数的返回值······
template<class R, class T, class... Args> class CCmd {
public:
CCmd(R (T::* fptr)(Args...), T * obj){}
auto call(Args&&... args) -> R {
auto func = std::mem_fun(mFunction);
return func(mObject, std::forward<Args>(args)...);
}
protected:
R (T::* mFunction)(Args...);
T * mObject;
};
template< class R, class T, class... Args> class CCommand : public CCmd<R,T,Args...> {
public:
CCommand(R (T::* fptr)(Args...), T * obj) :
CCmd<R,T,Args...>(fptr, obj) {
}
void Execute(std::vector<std::string> && parameters, std::string & returnValue) {
if(parameters.size() >= std::tuple_size<decltype(args)>::value) {
std::stringstream stream;
Parse(std::integral_constant<std::size_t, std::tuple_size<decltype(args)>::value - 1>{}, std::forward<decltype(args)>(args), std::forward<std::vector<std::string>>(parameters));
/* the following line fails, if R is of type void */
stream << CallFunc(typename GenerateArgumentIndexPack<std::tuple_size<decltype(args)>::value>::Pack());
stream >> returnValue;
} else {
returnValue = "not enough parameters";
}
}
protected:
std::tuple<Args...> args;
template <typename X, typename Y>
void Fill(const Y && input, X & output) {
std::stringstream stream;
stream << input;
stream >> output;
}
template<std::size_t N, typename... Ts>
void Parse(std::integral_constant<std::size_t, N>, std::tuple<Ts...>&& info, std::vector<std::string>&& tokens) {
Fill(std::forward<std::string>(tokens[N]), std::get<N>(info));
Parse(std::integral_constant<std::size_t, N - 1>{}, info, tokens);
}
template<typename... Ts>
void Parse(std::integral_constant<std::size_t, 0>, std::tuple<Ts...>&& info, std::vector<std::string>&& tokens) {
Fill(std::forward<std::string>(tokens[0]), std::get<0>(info));
}
template <std::size_t... ArgumentIndexes>
struct ArgumentIndexPack {};
template <std::size_t NumberOfArgumentIndexesToGenerate, std::size_t... GeneratedArgumentIndexes>
struct GenerateArgumentIndexPack : GenerateArgumentIndexPack<NumberOfArgumentIndexesToGenerate - 1, NumberOfArgumentIndexesToGenerate - 1, GeneratedArgumentIndexes...> {};
template <std::size_t... GeneratedArgumentIndexes>
struct GenerateArgumentIndexPack<0, GeneratedArgumentIndexes...> {
using Pack = ArgumentIndexPack<GeneratedArgumentIndexes...>;
};
template <std::size_t... ArgumentIndexes>
auto CallFunc(ArgumentIndexPack<ArgumentIndexes...>) -> R {
return CCmd<R,T,Args...>::call(std::forward<Args>(std::get<ArgumentIndexes>(args))...);
}
};
class CMyClass {
public:
void voidFunc() {
std::cout << "CMyClass::voidFunc" << std::endl;
}
void voidDoubleFunc(double d) {
std::cout << "CMyClass::voidDoubleFunc(" << d << ")" << std::endl;
}
};
int main(int argc, char** argv) {
CMyClass oMyClass;
CCommand<void, CMyClass> testObj0(&CMyClass::voidFunc, &oMyClass);
CCommand<void, CMyClass, double> testObj3(&CMyClass::voidDoubleFunc, &oMyClass);
std::string retval;
// This fails as get on a tuple with 0 elements seems to be invalid
testObj0.Execute({}, retval);
// This doesn't compile, as the voidDoubleFunc returns void
testObj3.Execute({"1.23", retval);
return 0;
}
g++ -c src/main.cpp -o src/main.o -std=c++11
在R T::F()上调用Execute时出现错误消息(1),其中R不是void类型:
src/main.cpp: In instantiation of 'void CCommand<R, T, Args>::Parse(std::integral_constant<long long unsigned int, N>, std::tuple<_Args2 ...>&&, std::vector<std::basic_string<char> >&&) [with long long unsigned int N = 18446744073709551615ull; Ts = {}; R = void; T = CMyClass; Args = {}]':
src/main.cpp:73:179: required from 'void CCommand<R, T, Args>::Execute(std::vector<std::basic_string<char> >&&, std::string&) [with R = void; T = CMyClass; Args = {}; std::string = std::basic_string<char>]'
src/main.cpp:147:31: required from here
src/main.cpp:98:68: error: no matching function for call to 'get(std::tuple<>&)'
Fill(std::forward<std::string>(tokens[N]), std::get<N>(info));
在空号T::F(args...)上调用Execute时出现错误消息(2)在那里Args...非无效:
src/main.cpp: In instantiation of 'void CCommand<R, T, Args>::Execute(std::vector<std::basic_string<char> >&&, std::string&) [with R = void; T = CMyClass; Args = {double}; std::string = std::basic_string<char>]':
src/main.cpp:156:43: required from here
src/main.cpp:76:11: error: no match for 'operator<<' (operand types are 'std::stringstream {aka std::basic_stringstream<char>}' and 'void')
stream << CallFunc(typename GenerateArgumentIndexPack<std::tuple_size<decltype(args)>::value>::Pack());
对于第一个问题,只需创建并重载parse
:
void Parse(std::integral_constant<std::size_t, -1>,
std::tuple<>&& info, std::vector<std::string>&& tokens) {
}
对于第二个问题(返回void
)的方法,可以对结果使用中间的struct
,并将CCMD
:
中间结构返回
:
template <typename R>
struct ReturnOf {
typedef R return_type;
};
template <>
struct ReturnOf<void> {
typedef std::string return_type;
};
template<class T, class... Args> class CCmd<void, T, Args...> {
public:
CCmd(void (T::* fptr)(Args...), T * obj) : mFunction(fptr), mObject(obj) { }
auto call(Args&&... args) -> std::string {
auto func = std::mem_fun(mFunction);
func(mObject, std::forward<Args>(args)...);
return std::string();
}
protected:
void (T::* mFunction)(Args...);
T * mObject;
};
template <std::size_t... ArgumentIndexes>
auto CallFunc(ArgumentIndexPack<ArgumentIndexes...>)
-> typename ReturnOf<R>::return_type {
...
}
问题内容: 我有一个返回字符串的Java实例方法,我正在C ++中通过JNI调用此方法。我写了以下代码: 如何获取字符串并将其转换为const char *? 我的程序在访问冲突为0x00000000的最后一行崩溃。returnString不是NULL。 问题答案: 根据,最后一个参数是的指针。 更改 至 或者更好的是,返回一个 我建立了一个类似的简单示例,到目前为止,代码看起来还不错。 虽然,有
我有一个Java实例方法,它返回一个字符串,我通过C中的JNI调用这个方法。我编写了以下代码: 如何获取字符串并将其转换为常量字符*? 我的程序在最后一行崩溃,访问冲突为0x00000000。returnString不为NULL。
我想知道是否可以在Kafka制作程序中配置2个不同的Kafka集群。 目前我正试图让我的制片人 我正在使用Apache Kafka 2.8和Python 3.7的confluent_kafka==1.8.2包。 生产商代码下方: 当我杀死clusterB时,我得到了以下错误消息。
问题内容: 我正在在线关注CS106A的讲座。我正在阅读第12讲中的代码,但这给了我Eclipse错误。 这是我的代码。似乎错误是由于我的方法中的单词void 。我尝试删除main方法,但是没有它,Java当然无法运行。 我是一名新手,没有人解释这东西的真正含义,但有人告诉我,请不要理会它并使用它。如果有人也可以向我解释,我将不胜感激。 这个错误也出现在“ toLower”方法上。不知道这意味着什
问题:返回给定字符串的一个版本,其中对于字符串中的每个星号(),其左右两侧的星号和字符都消失了。所以“abcd”产生“ad”,而“abcd”也产生“ad”。例如starOut(“abcd”)→ “ad”开始(“abcd”)→ “ad”starOut(“smeilly”)→ “傻” 我知道网上有答案,但我不想复制它们。我已经开始使用它的大部分内容,但不知道如何去掉空格并转换回字符串?如果你们有更好的
我有3个redis Sentinel的盒子设置: 在我的主人死后,哨兵进行了故障转移到R2。我将M1重新联机(清除了一些磁盘空间),现在M1还活着,但是是R2的奴隶。是否有一种自动的(或半自动的)方法,使M1再次成为主,R2再次成为M1和我的流量的从属,使用M1作为主redis实例?