如何创建递归可变参数模板以打印出参数包的内容?我正在尝试这个,但它无法编译:
template <typename First, typename ...Args>
std::string type_name () {
return std::string(typeid(First).name()) + " " + type_name<Args...>();
}
std::string type_name () {
return "";
}
Run Code Online (Sandbox Code Playgroud)
我该如何结束递归?
我正在尝试使用Visual C++ 11构建googletest,但是下面的代码会导致错误
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, // <-- error C2977
::std::ostream* os) {
PrintTupleTo(t, os);
}
Run Code Online (Sandbox Code Playgroud)
这是一个错误文本:
f:\gtest-1.6.0\include\gtest\gtest-printers.h(550): error C2977: 'std::tuple' : too many template arguments
c:\program files (x86)\microsoft visual studio 11.0\vc\include\utility(72) : see declaration of 'std::tuple'
Run Code Online (Sandbox Code Playgroud)
并且有utility-file 的第72行:
template<class = _Nil, _MAX_CLASS_LIST>
class tuple; // Line 72
Run Code Online (Sandbox Code Playgroud)
有什么问题std::tuple …
我想知道是否可以编写一个模板函数,可以将任何其他任意模板作为参数并正确匹配模板名称(即不仅仅是结果类).我所知道的工作是:
template<template<typename ...> class TemplateT, typename... TemplateP>
void f(const TemplateT<TemplateP...>& param);
Run Code Online (Sandbox Code Playgroud)
这将匹配例如用于f(std::vector<int>())或f(std::list<int>())但不会对工作f(std::array<int, 3>()),作为第二个参数是一个size_t无类型.
现在我想我可以做一些疯狂的事情:
template<template<typename ...> class TemplateT, size... Sizes, typename... TemplateP>
void f(const TemplateT<Sizes..., TemplateP...>& param);
Run Code Online (Sandbox Code Playgroud)
希望编译器能够正确地将TemplateP省略号或Sizes省略号导出为空.但它不仅难看,它仍然适用于采用任何类型或size_t参数的模板.它仍然不会匹配任意模板,例如bool参数.
对于重载方法也是如此:
template<template<typename ...> class TemplateT, typename... TemplateP>
void f(const TemplateT<TemplateP...>& param);
template<template<typename ...> class TemplateT, size... Sizes>
void f(const TemplateT<Sizes...>& param);
Run Code Online (Sandbox Code Playgroud)
此外,这种方法不会"工作,如果我们想混size_t和typenames.那么匹配任何内容所需要的就是这样的东西,其中对省略号中允许的内容没有任何限制:
template<template<...> class TemplateT, ... Anything>
void f(const TemplateT<Anything...>& param);
Run Code Online (Sandbox Code Playgroud)
该语法不起作用,但也许还有其他语法来定义这样的东西? …
似乎只能在别名模板的pack参数的位置扩展pack参数.对于类或函数模板,情况并非如此:
template <class T, class... Args> struct x { using type = T; };
template <class T, class... Args> using x_t = typename x<T, Args...>::type;
template <class... Args> using x_fix_t = typename x<Args...>::type;
template <class... Args> auto f(Args...) -> void {
typename x<Args...>::type v1; // OK
x_t<Args...> v2; // Error
x_fix_t<Args...> v3; // OK
}
Run Code Online (Sandbox Code Playgroud)
更简单的情况:
template <class T, class U> using y_t = T;
template <class... Args> auto f(Args...) -> void {
y_t<Args...> v4; // Error
} …Run Code Online (Sandbox Code Playgroud) c++ language-lawyer variadic-templates c++11 template-aliases
我有以下问题:
template< size_t... N_i >
class A
{
public:
// ...
void foo()
{
bar( /* 0,...,0 <- sizeof...(N_i) many */);
}
};
Run Code Online (Sandbox Code Playgroud)
我想调用一个函数并向它bar传递sizeof...(N_i)许多参数,这些参数都是零,例如,bar(0,0,0)以防万一sizeof...(N_i) == 3.如何实施?
我想编写一个函数,如果T是其中之一,则返回trueTs...
template<class T, class... Ts>
bool is_one_of<T, Ts...>();
Run Code Online (Sandbox Code Playgroud)
例如,is_one_of<int, double, int, float>收益true和is_one_of<int, double, std::string, bool, bool>回报false。
我自己的实现是
template<class T1, class T2>
bool is_one_of<T1, T2>() {
return std::is_same<T1, T2>;
}
template<class T1, class T2, class... Ts>
bool is_one_of<T1, T2, Ts...>() {
if (std::is_same<T1, T2>) {
return true;
}
else {
return is_one_of<T1, Ts...>();
}
}
Run Code Online (Sandbox Code Playgroud)
这种检查对我来说似乎很常见,所以我想知道标准库中是否已经有这样的功能。
以下文章是我为模板参数包找到的第一个提案.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1603.pdf
在第16页,它讨论了引入两个新的运算符[]和<>来访问参数包元素和参数包类型.
The suggested syntax for such an operator involves two new operators: .[] to access values and .<> to access types. For instance:
template<int N, typename Tuple> struct tuple_element;
template<int N, ... Elements>
struct tuple_element<tuple<Elements...> >
{
typedef Elements.<N> type;
};
template<int N, ... Elements>
Elements.<N>& get(tuple<Elements...>& t)
{ return t.[N]; }
template<int N, ... Elements>
const Elements.<N>& get(const tuple<Elements...>& t)
{ return t.[N]; }
Run Code Online (Sandbox Code Playgroud)
那么这些运营商在哪里?如果没有,他们的替代品是什么?
以下3个gun函数调用有什么区别?
template <class... Ts> void fun(Ts... vs) {
gun(A<Ts...>::hun(vs)...);
gun(A<Ts...>::hun(vs...));
gun(A<Ts>::hun(vs)...);
}
Run Code Online (Sandbox Code Playgroud)
我对使用特定示例解释三个调用的答案感兴趣.
我有一个模板'Foo',它拥有一个T,我希望它有一个可变参数构造函数,将它的参数转发给T的构造函数:
template<typename T>
struct Foo {
Foo()
: t() {}
Foo(const Foo& other)
: t(other.t) {}
template<typename ...Args>
Foo(Args&&... args)
: t(std::forward<Args>(args)...) {}
T t;
};
Run Code Online (Sandbox Code Playgroud)
但是,这会导致Foo无法复制:
int main(int argc, char* argv[]) {
Foo<std::shared_ptr<int>> x(new int(42));
decltype(x) copy_of_x(x); // FAILS TO COMPILE
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
因为,根据这个答案,参数的非常量导致可变参数构造函数更好地匹配.出于显而易见的原因,我不想强制我的调用者使用const_cast.
我找到的一个可能的解决方案是为Foo编写一个"复制构造函数",它采用非const Foo并使用构造函数转发:
Foo(Foo& other)
: Foo(const_cast<const Foo&>(other)) {}
Run Code Online (Sandbox Code Playgroud)
当定义了这个构造函数时,事情再次起作用:现在首选非const Foo参数copy ctor.然而,这对我来说似乎非常粗略,因为这种"治愈"似乎比疾病更糟糕.
是否有另一种方法来实现这种效果,表明自然拷贝构造函数应该优先于可变参数构造函数?如果没有,定义这个非const参数复制构造函数会有什么不利后果吗?
std::visit()在cppreference中查看页面时,https: //en.cppreference.com/w/cpp/utility/variant/visit,
我遇到了我无法理解的代码......
这是缩写版本:
#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
#include <variant>
#include <vector>
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;
int main() {
std::vector<std::variant<int,long,double,std::string>> vec = { 10, 15l, 1.5, "hello" };
for (auto& v : vec) {
std::visit(overloaded{
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << …Run Code Online (Sandbox Code Playgroud)