标签: variadic

C99中带有0个参数的变量宏

我有一些调试代码如下所示:

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
void __my_error(const char*loc, const char *fmt, ...);
#define my_error(fmt, ...) __my_error(AT, fmt, ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

使用最后一个宏,因此我可以将位置插入到调试输出中,以确定错误发生的位置.但是,当我调用这样的函数时:

my_error("Uh oh!");
Run Code Online (Sandbox Code Playgroud)

喜欢我的代码是C99,所以我觉得这个时候编译,我得到以下错误:

error: ISO C99 requires rest arguments to be used
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过改变呼叫来解决这个问题

my_error("Uh oh!", NULL);
Run Code Online (Sandbox Code Playgroud)

但有什么方法可以让这个看起来不那么难看?谢谢!

macros c99 variadic

10
推荐指数
1
解决办法
7720
查看次数

传递对Variadic模板的引用

我正在研究一个事件库,我遇到了Variadic模板的问题.

一切都工作得非常好,除了我不能将参考作为参数传递...

这是一个非常简化的例子,用来揭露我的问题.

struct DelayedSignal 
{   
    ~DelayedSignal ()
    { std::cout << "~DelayedSignal CLOSE" << std::endl; }

    template<class C, class... Args>
    DelayedSignal ( void(C::*func)(Args...), C& obj )
    { std::cout << "DelayedSignal INIT - 03 - pointer to method & pointer to class instance (Arg num: " << sizeof...(Args) << ")" << std::endl; }

    template<class C, class... Args>
    DelayedSignal ( void(C::*func)(Args...), C& obj, Args... args )
    {
        std::cout << "DelayedSignal INIT - 04 - pointer to method & pointer to class instance …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic c++11

10
推荐指数
1
解决办法
1994
查看次数

包含不同的功能?

我正在尝试为不同的函数实现一个容器类,我可以在其中保存函数指针并使用它来稍后调用这些函数.我会尝试更准确地描述我的问题.

例如,我有两种不同的测试功能:

int func1(int a, int b) { 
    printf("func1 works! %i %i\n", a, b);
    return 0;
}
void func2(double a, double b) {
    printf("func2 works! %.2lf %.2lf\n", a, b);
}
Run Code Online (Sandbox Code Playgroud)

我还有一系列变体,它们包含函数参数:

std::vector<boost::variant<int, double>> args = {2.2, 3.3};
Run Code Online (Sandbox Code Playgroud)

我已经决定使用从某个基类派生的我自己的仿函数类(我考虑过使用虚方法):

class BaseFunc {
public:
    BaseFunc() {}
    ~BaseFunc() {}
};

template <typename T>
class Func;

template <typename R, typename... Tn>
class Func<R(Tn...)> : public BaseFunc {
    typedef R(*fptr_t)(Tn...);
    fptr_t fptr;
public:
    Func() : fptr(nullptr) {}
    Func(fptr_t f) : fptr(f) {}
    R operator()(Tn... args) …
Run Code Online (Sandbox Code Playgroud)

c++ containers templates variadic functor

10
推荐指数
1
解决办法
204
查看次数

它是编译器还是仅仅是我:继承自lambda所包含的可变参数模板

我有一些代码在GCC下工作,但无法在Visual Studio 2015下编译(我意识到它正在开发中,但我认为应该实现这个领域).

template< typename... T >
class inherit : public T...
{
public:
inherit(T... t) : T(t)... {}
};

int main() {
  auto l1 = []() {};
  auto l2 = []() {};
  inherit<decltype(l1), decltype(l2)> test(l1, l2);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是代码片段简化为它的纯粹本质.Visual Studio在继承的构造函数上说"语法错误:'type'".然后它会稍微探讨它是如何到达那里的,并以"你不能构建一个lambda实例"结束.

我的假设是T(t)的扩展......没有正确扩展.但是我可能会错误地使用语法.

编辑:对不起,问题是:我在这里有错吗?如果是这样,那么正确的语法是什么?

其他发现:为了与我所拥有的回复保持一致,这似乎是Visual Studio 2015在此领域存在错误的问题.在测试中,它似乎是扩展,其中构造函数params被传递给具有问题的lambda基类.以下测试在VS2015下运行:

template< typename T1, typename T2, typename... T3 >
class inherit2 : public T3...
{
public:
  inherit2(T1 t1, T2 t2) : T1(t1), T2(t2) {}
};

int main() {
  auto l1 = []() …
Run Code Online (Sandbox Code Playgroud)

lambda templates variadic c++11 visual-studio-2015

10
推荐指数
1
解决办法
236
查看次数

将零参数包传递给printf

我创建了一个具有可变参数模板方法的类.这个方法调用printf函数.将零参数传递给方法时,我得到gcc的编译警告说:

警告:格式不是字符串文字而没有格式参数[-Wformat-security]

一个简化的类示例是:

class printer{
    std::map<int,std::string> str;
  public:
    printer(){
      str[0] = "null\n";
      str[1] = "%4d\n";
      str[2] = "%4d %4d\n";
      str[3] = "%4d %4d\n%4d\n";
    }
    template<typename ...Args>
    void print(Args... args){
      printf(str[sizeof...(args)].c_str(),args...);
    }
};
Run Code Online (Sandbox Code Playgroud)

使用时

printer p;
p.print(23);
p.print(345,23);
Run Code Online (Sandbox Code Playgroud)

一切顺利,但使用时

printer p;
p.print();
Run Code Online (Sandbox Code Playgroud)

我收到编译警告

main.cpp: In instantiation of ‘void printer::print(Args ...) [with Args = {}]’:
main.cpp:23:11:   required from here
main.cpp:17:50: warning: format not a string literal and no format arguments [-Wformat-security]
       printf(str[sizeof...(args)].c_str(),args...);
Run Code Online (Sandbox Code Playgroud)

当然,如果我只是打电话

printf("null\n");
Run Code Online (Sandbox Code Playgroud)

没有警告出现.

有人可以解释为什么会这样吗?

我可以在不禁用-Wformat-security标志的情况下删除警告吗?

c++ gcc variadic

10
推荐指数
1
解决办法
682
查看次数

传递许多函数并将所有结果存储在元组中

考虑这个输出:

int foo (int, char) {std::cout << "foo\n";  return 0;}
double bar (bool, double, long ) {std::cout << "bar\n";  return 3.5;}
bool baz (char, short, float) {std::cout << "baz\n";  return true;}

int main() {
    const auto tuple = std::make_tuple(5, 'a', true, 3.5, 1000, 't', 2, 5.8);
    multiFunction<2,3,3> (tuple, foo, bar, baz);  // foo  bar  baz
}
Run Code Online (Sandbox Code Playgroud)

因此,multiFunction<2,3,3>获取前2个元素tuple并将它们传递给foo接下来的3个元素tuple并将它们传递给bar等等...我得到了这个工作(除非函数有重载,这是一个单独的问题).但是所调用的每个函数的返回值都会丢失.我希望将这些返回值存储在某处,例如

std::tuple<int, double, bool> result = multiFunction<2,3,3> (tuple, foo, bar, baz);
Run Code Online (Sandbox Code Playgroud)

但我不知道如何实现这一点.对于那些想要帮助完成这项工作的人来说,这是我目前为止的(更新的)工作代码,它仅将输出存储到字符串流中.不容易获得所有值,特别是如果流中保存的对象是复杂类.

#include <iostream> …
Run Code Online (Sandbox Code Playgroud)

c++ templates tuples variadic c++14

10
推荐指数
1
解决办法
395
查看次数

迭代C++可变参数模板

我有以下内容:

template<typename FIRST, typename SECOND>
Sender *createSenderChain() {
    return new FIRST(new SECOND());
}
Run Code Online (Sandbox Code Playgroud)

是否可以使模板可变:

template<typename FIRST, typename ...Args>
Sender *createSenderChain() {
    return new FIRST(new SECOND(new THIRD(new ...))  <-- This is the pattern I want, 
                                                         but how should it be done 
                                                         using the args list?
}
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic

10
推荐指数
2
解决办法
3319
查看次数

传递可变数量的参数

我们可以将可变数量的参数传递给c中的函数吗?

c function variadic variadic-functions

9
推荐指数
2
解决办法
917
查看次数

在Swift 4中为os_log传递可变参数args

我正在尝试为Swift 4/iOS 11中的os_log编写一个方便的包装器,但是我已经遇到了传递可变参数的艰难战斗.

基本上,我想编写一个如下所示的函数.

static let logger = OSLog(subsystem: "com.example.foo", category: "foobar")
func logError(_ message: StaticString, _ args: Any...) {
    os_log(message, log: logger, type: .error, args)
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我似乎无法弄清楚传递参数的神奇语法,并且在CVarArg讨论的泥潭中有点迷失.

(...这让我想念Python的splatting语法)

variadic ios swift4

9
推荐指数
2
解决办法
1710
查看次数

具有多个相同类型参数的模板函数

我正在尝试创建一个函数,该函数可以采用相同类型的多个参数,并作为模板传入。参数的数量在编译时是已知的:

struct Foo
{
    int a, b, c;
};

template <uint32_t argsCount, typename T>
void fun(T ...args) // max number of args == argsCount
{
    // ...
    // std::array<T, argsCount>{ args... };
}

int main()
{
    fun<3, Foo>( { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } );

    // Dont want to do:
    // fun( Foo{}, Foo{}, Foo{} );
    // nor:
    // fun<Foo, Foo, Foo>( ... );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我必须考虑这些限制:

  • 没有堆内存分配
  • 没有 va_args …

c++ templates variadic c++14

9
推荐指数
3
解决办法
2904
查看次数