函数,该函数接受大括号构造对象的可变模板列表
Function that accepts variadic template list of brace constructed objects
你好,模板元编程专家。
我正在尝试编写一个(类成员)函数,理想情况下可以将其作为一个参数,称为类型不可知映射。
理想情况下类似于:
foo({"Bar", 42}, {"Baz", "Blargh");
以及:
foo({"Blargh", "Bleh"}, {"Biz", 43.6}, {"Bam", {43, 43, 43}});
然后,类/函数应该能够通过调用在编译时推导的转换函数来转换这些参数,因此它在内部最终会得到一个以字符串为键和值的std::映射。
原因仅仅是句法上的糖。在我的用例中,如果提供了不受支持的类型,那么调用方就不必担心转换参数和编译时出错,这将非常方便。
如果调用方显式使用make_pair,如中所示,我已经使其工作
foo(std::make_pair<std::string, std::chrono::miliseconds>("Time", 42));
但这自然不是很干净,也绝对不会比调用方自己将值类型转换为std::string更方便。
我曾尝试创建自己的std::pair类,并对各种值类型进行专门化,但如果我使用大括号初始值设定项进行调用,就像使用标准std::map一样,我的编译器(gcc)无法找到它。我的编译器似乎将其视为std::initializer_list,即使参数具有不同的类型。
我或多或少得出的结论是,即使在C++14标准中,我所尝试的也是不可能的,但我并不完全确定。
有没有人对如何解决这个问题有任何想法,或者能够解释为什么如果是这样的话,这是不可能的?
非常感谢!
编辑
示例代码:
template<typename Value, typename... Args>
void foo(const std::pair<std::string, Value>& val, Args... args)
{
foo(args...);
}
void foo(const std::pair<std::string, int>& val) {}
void foo(){}
调用foo()如下:
foo({"key", 42});
不扩展模板并且有效,而:
foo({"key", 42}, {"another", 53})
编译失败,错误为:
no matching function for call to ‘foo(<brace-enclosed initializer list>, <brace-enclosed initializer list>)’
我猜下面的代码:
template <typename... Ts>
void foo(Ts... ts) {}
foo({1,2}, {3,4});
由于与完全相同的原因而无法编译
template <typename T>
void foo(T t) {}
foo({1,2});
即大括号封闭列表根本没有类型,因此无法推导。
然而,知道大括号包围的初始值设定项列表可以通过非显式构造函数来初始化具体类型,并且编译器能够推导出std::initializer_list<T>
的T
类型,使用老式可变列表的以下代码可以按预期工作:
#include <initializer_list>
struct AgnosticMap
{
AgnosticMap(std::nullptr_t) {}
template <typename T, typename U>
AgnosticMap(T t, U u) {}
template <typename T, typename U>
AgnosticMap(T t, std::initializer_list<U> il) {}
};
void foo(AgnosticMap a1
, AgnosticMap a2 = nullptr
, AgnosticMap a3 = nullptr
, AgnosticMap a4 = nullptr)
{
}
int main()
{
foo({"Blargh", "Bleh"}, {"Biz", 43.6}, {"Bam", {43, 43, 43}});
}
DEMO
我可以想象的一个解决方案是使用可变模板:
template<typename T, typename U, typename... Rest>
auto foo(T t, U u, Rest... rest){
//deal with t and u,
//and call foo(rest...) recursievely
}
- 如何使用单独文件中的派生类访问友元函数对象
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- 有没有办法将重载的类函数绑定到函数对象?
- 将指针传递到成员的指针,从模板参数包到函数对象
- 如何在类模板的成员函数中正确调用函数对象?正在生成 Visual Studio 编译器错误 C2440
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- C++使用函数对象的线程,如何调用多个析构函数而不是构造函数?
- 如何通过接口将函子分配给函数对象
- 对std::函数对象的调用不匹配,该对象是指向成员函数的指针
- 指向std::invoke中成员函数对象的指针
- 如何成功地将函数对象(或lambda)传递给trackbar回调的第二个参数(void*)
- "std::function"的简单版本:函数对象的生存期?
- C++ 将函数对象作为左值和/或右值传递
- SFINAE 用于具有默认参数的函数对象
- 构造函数对象赋值是否泄漏内存
- 如何发送通过绑定到函数/方法创建的函数对象?
- std::for_each 与函数对象
- 将函数对象传递给 std::function
- 访问执行策略for_each函数对象中的迭代器
- 通过C++函数对象类访问参数