我想知道是否有任何方法可以动态地将参数传递给可变参数函数.即如果我有一个功能
int some_function (int a, int b, ...){/*blah*/}
Run Code Online (Sandbox Code Playgroud)
我接受用户的一堆值,我想要一些方法将这些值传递给函数:
some_function (a,b, val1,val2,...,valn)
Run Code Online (Sandbox Code Playgroud)
我不想写所有这些功能的不同版本,但我怀疑没有其他选择?
我最近解决了构造函数问题,其中相互装饰的各种mixins类(和最顶层的宿主类)具有不同的构造函数签名。为了在产生的修饰类中维护单个构造函数,并且不添加init函数,我找到了以下解决方案。它对mixin类的唯一限制是,如果其构造函数使用多个参数,则应将它们全部封装在一个元组中。(使用g ++编译此代码需要-std = c ++ 0x标志)
#include <boost/tuple/tuple.hpp>
// Base class for all mixins
struct Host {
float f_;
int i_;
Host(float f, int i) : f_(f), i_(i) {}
};
// First mixin--constructs with 1 parameter
template <class B>
struct M1 : public B {
char c_;
template <class... A>
M1(char c, const A&... a) : B(a...), c_(c) {}
};
// Second mixin--constructs with 3 parameters
template <class B>
struct M2 : public B {
double d_;
short …Run Code Online (Sandbox Code Playgroud) 如何在c ++中访问lambda函数的参数类型?以下不起作用:
template <class T> struct capture_lambda {
};
template <class R, class T> struct capture_lambda<R(T)> {
static void exec() {
}
};
template <class T> void test(T t) {
capture_lambda<T>::exec();
}
int main() {
test([](int i)->int{ return 0; });
}
Run Code Online (Sandbox Code Playgroud)
上面没有编译,因为编译器选择模板原型而不是专门化.
有没有办法做到这一点?
我实际上想要实现的是:我有一个函数列表,我想选择适当的函数来调用.例:
template <class T, class ...F> void exec(T t, F... f...) {
//select the appropriate function from 'F' to invoke, based on match with T.
}
Run Code Online (Sandbox Code Playgroud)
例如,我想调用带'int'的函数:
exec(1, [](char c){ printf("Error"); }, [](int i){ printf("Ok"); });
Run Code Online (Sandbox Code Playgroud) 我在看“如何正确使用可变参数模板的引用”,并想知道逗号扩展可以走多远。
这是答案的一个变体:
inline void inc() { }
template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t; inc(args...); }
Run Code Online (Sandbox Code Playgroud)
由于可变参数被扩展到一逗号-分隔它们的元素的列表,是那些逗号语义上等同于模板/功能参数的分离器,或者他们插入词法,使得它们适用于任何(-预处理后)的使用,包括逗号操作符?
这适用于我的 GCC-4.6:
// Use the same zero-argument "inc"
template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t, inc(args...); }
Run Code Online (Sandbox Code Playgroud)
但是当我尝试时:
// Use the same zero-argument "inc"
template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t, ++args...; }
Run Code Online (Sandbox Code Playgroud)
我不断收到解析错误,期待“;” 在“...”之前,并且“args”不会扩展其包。为什么不起作用?是因为如果“args”为空,我们会得到一个无效的标点符号?合法吗,我的编译器不够好?
(我试过在括号中围绕“args”,和/或使用后增量;都没有奏效。)
在以下代码中:
#include <iostream>
struct Base {
virtual ~Base() = default;
template <typename T, typename... Args> void helper (void (T::*)(Args..., int), Args...);
void bar (int n) {std::cout << "bar " << n << std::endl;}
};
struct Derived : Base {
void baz (double d, int n) {std::cout << "baz " << d << ' ' << n << std::endl;}
};
template <typename T, typename... Args>
void Base::helper (void (T::*f)(Args..., int), Args... args) {
// A bunch on lines here (hence the …Run Code Online (Sandbox Code Playgroud) 我得到一个"错误的模板参数数量(2,应该是1)"错误,我无法理解.
我有一个类为其他想要与之交互的类型提供一些辅助函数,设置第一个模板参数,在创建时它们必须自动相互兼容.为了以方便,通用的方式执行此操作,我决定使用可变参数模板,该模板旨在传递构造函数参数和要创建的对象类型的其他模板参数:
template<typename INTERNAL_TYPE>
class Linker
{
template< template<typename, typename ...> class INPUT_OBJ_TYPE, class ... TEMPLATE_ARGS, class ... CONSTRUCTOR_ARGS >
std::shared_ptr< INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS ...> > getLinked( CONSTRUCTOR_ARGS ... args )
{
std::shared_ptr< INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS ...> > ptr = std::make_shared< INPUT_OBJ_TYPE<INTERNAL_TYPE,TEMPLATE_ARGS ...> >( args... );
return ptr;
}
};
Run Code Online (Sandbox Code Playgroud)
这适用于以下类:
template<typename INTERNAL_TYPE, typename SECOND_TYPE>
class TEST_CLASS_1
{};
Run Code Online (Sandbox Code Playgroud)
也就是说,我可以做到以下几点:
Linker<int> container;
auto test_1 = container.getLinked<TEST_CLASS_1,double>();
Run Code Online (Sandbox Code Playgroud)
然后我尝试对另一个只在一个参数上进行模板化的类做同样的事情:
template<typename INTERNAL_TYPE>
class TEST_CLASS_2
{};
auto test_2 = container.getLinked<TEST_CLASS_2>();
Run Code Online (Sandbox Code Playgroud)
但得到上面提到的错误..为什么?如果我从函数声明/定义中删除了TEMPLATE_ARGS,那么我可以使用代码编写第二个测试(尽管第一个测试不再编译).所以我认为那时的编译器还没有意识到TEMPLATE_ARGS对于第二次测试是空的,并且因为有太多的模板参数而引发错误.所以我想我可能需要使用跟踪返回类型
template< template<typename, typename ...> class INPUT_OBJ_TYPE,
class ... …Run Code Online (Sandbox Code Playgroud) 我使用名为 fmt 的格式化库(http://fmtlib.net/latest/)。
可能的用途之一是:
fmt::format("Hello, {name}! The answer is {number}. Goodbye, {name}.", fmt::arg("name", "World"), fmt::arg("number", 42));
Run Code Online (Sandbox Code Playgroud)
我想将此调用包装在一个函数中,我将其调用为:
myFunction(myString, {"name", "World"}, {"number", 42});
Run Code Online (Sandbox Code Playgroud)
对于任意数量的参数。
到目前为止,我只成功地完成了一个可使用成对列表调用的函数:
myFunction(myString, std::make_pair("name", "World"), std::make_pair("number", 42));
Run Code Online (Sandbox Code Playgroud)
具有以下功能:
std::string myFunction(const char* str, const Args&... rest) const
{
return fmt::format(mLocale.getPOILabel(label), fmt::arg(rest.first, rest.second)...);
}
Run Code Online (Sandbox Code Playgroud)
但我不想使用成对的。
我应该怎么办 ?
PS:fmt::arg不能在函数之间传递。
该类typing.Tuple可以与任意数量的类型参数一起使用,例如Tuple[int, str, MyClass]或Tuple[str, float]。我如何实现我自己的可以像这样使用的类?我了解如何继承typing.Generic. 下面的代码演示了这一点。
from typing import TypeVar, Generic
T = TypeVar("T")
class Thing(Generic[T]):
def __init__(self, value: T):
self.value = value
def f(thing: Thing[int]):
print(thing.value)
if __name__ == '__main__':
t = Thing("WTF")
f(t)
Run Code Online (Sandbox Code Playgroud)
t上面的代码可以工作,但是类型检查器(在我的例子中是 PyCharm)会捕获应该是类型Thing[int]而不是 的事实Thing[str]。这一切都很好,但是如何让该类Thing支持任意数量的类型参数,就像Tuple那样?
假设我想要一种策略来一次清除多个假设,做类似clear_multiple H1, H2, H3.. 我尝试使用对来做到这一点,如下所示:
Ltac clear_multiple arg :=
match arg with
| (?f, ?s) => clear s; clear_multiple f
| ?f => clear f
end.
Run Code Online (Sandbox Code Playgroud)
但是,问题是我必须放置括号才能有一个Prod:
Variable A: Prop.
Goal A -> A -> A -> True.
intros.
clear_multiple (H, H0, H1).
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何在不使用Prods 的情况下做到这一点?
我检查了这个问题,但这不是我想要的,因为我想要的参数数量未知。
我继承了以下内容:
template <typename T>
concept IsAwaiter = requires {
typename T::await_ready;
typename T::await_suspend;
typename T::await_resume;
};
template <typename ...AWAITABLES>
concept IsAwaitables = typename std::conjunction<IsAwaiter<AWAITABLES>...>::type;
Run Code Online (Sandbox Code Playgroud)
使用 clang 10.0.0 构建它会导致以下错误:
IsAwaiter.h:43:50: error: template argument for template type parameter must be a type
Run Code Online (Sandbox Code Playgroud)
也许只是一个简单的语法问题,但我发现很难找到一个示例来展示如何基于可变参数模板概念参数创建概念。
任何帮助表示赞赏!