我有以下模板化功能......
template< class T > T *create_object( lua_State *L )
{
// Get a raw block of memory, managed by Lua.
void *mem = lua_newuserdata( L, sizeof( T ) );
// Construct the object in the allocated memory.
T *object = new (mem) T;
// Do other stuff here...
return object;
}
Run Code Online (Sandbox Code Playgroud)
...分配并设置一个C++对象,以便在Lua脚本语言中使用.我想扩展这个函数,这样我就可以传入对象构造函数的参数.它可能看起来像这样:
template< class T > T *create_object( lua_State *L, ??? ctor_args )
{
void *mem = lua_newuserdata( L, sizeof( T ) );
T *object = new (mem) T( …Run Code Online (Sandbox Code Playgroud) variadic宏提到了关于gcc的VA_ARGS.
我做了以下实验.
#define EVAL(f,...) eval(f,build_args(args,__VA_ARGS__ , args_end))
Run Code Online (Sandbox Code Playgroud)
和
EVAL(f,a) // => eval(f,build_args(args,a, args_end))
EVAL(f,a,b) // => eval(f,build_args(args,a,b, args_end))
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好,但是
EVAL(f) // => eval(f,build_args(args, , args_end))
Run Code Online (Sandbox Code Playgroud)
我必须提供至少一个参数,我根据手册解决问题,使用'##'.
#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,a) // => eval(f,build_args(args,a, args_end))
EVAL(f,a,b) // => eval(f,build_args(args,a,b, args_end))
EVAL(f) // => eval(f,build_args(args, args_end))
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好,但是
#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,EVAL(g,a)) // => eval(f,build_args(args,EVAL(g,a) , args_end))
Run Code Online (Sandbox Code Playgroud)
我们可以看到第二个EVAL没有扩展,但没有'##',第二个EVAL是扩展的.
#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,EVAL(g,a)) // => eval(f,build_args(args,
// eval(g,build_args(args,a , args_end),
// …Run Code Online (Sandbox Code Playgroud) 我的代码使用 GCC 生成语法错误:
Run Code Online (Sandbox Code Playgroud)src/main.cpp: In function ‘int main()’: src/main.cpp:95:4: error: could not convert ‘{{"enum", E_PRINT}, {"string", "setup"}, {"object", {{"double", 3.1415926535897931e+0}, {"long", 1235813l}}}}’ from ‘<brace-enclosed initializer list>’ to ‘Object’ };
#include <cmath>
#include <initializer_list>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include <stdlib.h>
struct NamedValueBase {
NamedValueBase( const std::string & name ) :
name( name )
{}
virtual ~ NamedValueBase( void ) {}
std::string name;
};
template<class T>
struct NamedValue : public NamedValueBase {
NamedValue( const std::string & …Run Code Online (Sandbox Code Playgroud) 假设我有一个
trait Happy {}
Run Code Online (Sandbox Code Playgroud)
我可以Happy为任何我想要的结构实现,例如:
struct Dog;
struct Cat;
struct Alligator;
impl Happy for Dog {}
impl Happy for Cat {}
impl Happy for Alligator {}
Run Code Online (Sandbox Code Playgroud)
现在,我想自动为所有由所有实现该特征的类型组成的元组使用impl我Happy的Happy特征。从直觉上讲,所有快乐的元组也是快乐的。
可以做这样的事情吗?例如,我可以简单地将实现扩展Happy到两种Happy类型的元组:
impl <T, Q> Happy for (T, Q) where T: Happy, Q: Happy {}
Run Code Online (Sandbox Code Playgroud)
结果,这可以完美地编译:
fn f(_: impl Happy) {
}
fn main() {
f((Dog{}, Alligator{}));
}
Run Code Online (Sandbox Code Playgroud)
但是我怎么能将其推广到任何长度的元组呢?据我所知,Rust中没有可变参数的泛型。有解决方法吗?
出于某种原因,我似乎无法将此操作与 C++11 一起使用。
template<typename T>
int value(){ return 1;}
template<typename T1>
constexpr int SumCpp11(){
return value<T1>();
}
template<typename T1, typename... T>
constexpr int SumCpp11(){
return value<T1>() + SumCpp11<T...>();
}
int main(int argc, char* argv[])
{
return SumCpp11<int, int, double, double>();
}
Run Code Online (Sandbox Code Playgroud)
编译器愉快地展开递归直到终止,然后抱怨不明确的声明。我已经反复修改了这个。我不能使用初始化列表技巧,因为我需要留在 C++11 中,这需要是一个 constexpr,因为这个最终值在代码的另一部分被用作模板参数。
clang++ --std=c++11 tailVar.cpp
tailVar.cpp:13:24: error: call to 'SumCpp11' is ambiguous
return value<T1>() + SumCpp11<T...>();
^~~~~~~~~~~~~~
tailVar.cpp:13:24: note: in instantiation of function template specialization 'SumCpp11<double, double>' requested here
tailVar.cpp:13:24: note: in instantiation of function template specialization …Run Code Online (Sandbox Code Playgroud) 在下面的代码片段中,我使用了可变参数模板 findSum 函数,并确保该函数的参数类型使用概念相同,但有人可以建议我如何确保该函数的返回类型也与参数类型匹配。
#include <iostream>
#include <concepts>
template<typename F,typename... R>
struct FirstVariadicType
{
using Type = F;
};
template<typename... Ts>
requires requires(Ts... args){
std::conjunction_v<std::is_same<typename FirstVariadicType<Ts...>::Type, Ts>...>;
}
auto findSum(Ts... args)
{
return (... + args);
}
int main()
{
std::cout<<"sum of 2 and 3 is "<<findSum(2,3)<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我写了以下程序
#include <iostream>
template<typename C, typename Res, typename... Args>
class bind_class_t {
private:
Res (C::*f)(Args...);
C *c;
public:
bind_class_t(Res (C::*f)(Args...), C* c) : f(f), c(c) { }
Res operator() (Args... args) {
return (c->*f)(args...);
}
};
template<typename C, typename Res, typename... Args>
bind_class_t<C, Res, Args...>
bind_class(Res (C::*f)(Args...), C* c) {
return bind_class<C, Res, Args...>(f, c);
}
class test {
public:
int add(int x, int y) {
return x + y;
}
};
int main() {
test t;
// bind_class_t<test, int, …Run Code Online (Sandbox Code Playgroud) c89 gcc 4.7.4
你好,
我只是试验这些宏:
#define LOG_INFO_1(fmt, ...) printf(fmt, __VA_ARGS__)
#define LOG_INFO_2(...) printf(__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
并使用这样:
LOG_INFO_1("%s:%d", __func__, __LINE__);
LOG_INFO_2("%s:%d", __func__, __LINE__);
Run Code Online (Sandbox Code Playgroud)
输出提供完全相同的格式.我只是想知道fmt在我的第一个宏中使用参数有什么好处?它似乎并不是真的需要.我怎么能利用它呢?
非常感谢任何建议,
我希望能够使用模板包声明一个类,这样类本身将有一个成员变量元组,它将每个模板包成员包装在某种容器类型中.基本目标如下:
template <typename Types...>
class VectorOfMembers
{
public:
// Member tuple where each element is expanded in a container
std::tuple<std::vector<Type[1]>, std::vector<Type[2]>, std::vector<TypeN...>>
};
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望能够将任何模板化对象作为包装类型.
因此,我正在做一些作业,其中我必须在C ++ 11中编写自己的编译时整数序列,并为其编写一些函数(print,concat,sort等),但是我有点缠着我的头如何写这些东西的麻烦。
template<typename T, typename Comp = std::less<int>>
struct Facility{
template<T ... Nums>
struct List{
struct Element<T ... nums>{};
template<unsigned num, T val, T ... rest>
struct Element{
unsigned index = num;
T value = val;
Element<index-1, rest...> others;
};
template<unsigned num, T val, T ... rest>
struct Element<0, val>{
unsigned index = 0;
T value = val;
};
static constexpr Element<sizeof...(Nums)-1,Nums...> elem = {};
static void Print()
{
// Prints out the list
}
};
};
using IntList …Run Code Online (Sandbox Code Playgroud)