- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这是我的定义:
template<typename ... TL>
struct TemplatedType { };
template<typename ... TL>
std::istream& operator>>(std::istream& is, TemplatedType<TL ...> & sp)
{
// do stuff
return is;
}
和用法:
std::istringstream iss("I'd like some pancakes, please");
TemplatedType<int> a;
iss >> a;
它工作得很好,但是我想接收模板化参数作为右值引用:
template<typename ... TL>
std::istream& operator>>(std::istream& is, const TemplatedType<TL && ...> & sp) {...}
然后,编译器开始大喊:
C2678 binary '>>': no operator found which takes a left-hand operand of type 'std::istringstream' (or there is no acceptable conversion)
问题出在哪里?
动机:我想制作一个可以以这种方式使用的 split
函数:
std::istringstream iss("alpha:=10/50.1");
std::string x;
int y;
double z;
iss >> split(x, ':', '=', y, '/', z); // sets x=alpha, y=10, z=50.1
因此该函数需要能够接收左值和右值引用。
最佳答案
有趣的问题。
Jarod42 解释了问题出在哪里:如果你定义一个 TemplatedType<int> a;
, 这可以匹配
template<typename ... TL>
std::istream& operator>>(std::istream& is,
const TemplatedType<TL ...> & sp)
但无法匹配
template<typename ... TL>
std::istream& operator>>(std::istream& is,
const TemplatedType<TL & ...> & sp)
因为你有一个 int
并且需要 int&
.
但是如何开始工作
iss >> split(x, ':', '=', y, '/', z);
?
嗯...我想你可以放一个std::tuple
里面TemplatedType
template <typename ... TL>
struct TemplatedType
{ std::tuple<TL...> t; };
所以 split()
(我已将其重命名为 mySplit()
)简单地变成了
template <typename ... TL>
TemplatedType<TL...> mySplit (TL && ... al)
{ return { std::forward_as_tuple(al...) }; }
从
mySplit(x, ':', '=', y, '/', z);
哪里x
是 std::string
, y
是 int
和 z
是 double
, 你获得一个 TemplatedType<std::string &, char, char, int &, char, double &>
.
你可以写一个operator<<()
调用第一个辅助函数
template <typename ... TL>
std::istream & operator>> (std::istream & is,
TemplatedType<TL...> const & sp)
{
myHelper1(is, sp, std::index_sequence_for<TL...>{});
return is;
}
第一个辅助函数提取元组中包含的元素 sp
并调用第二个辅助函数
template <typename ... TL, std::size_t ... IL>
void myHelper1 (std::istream & is,
TemplatedType<TL...> const & sp,
std::index_sequence<IL...> const &)
{ myHelper2(is, std::get<IL>(sp.t)...); }
第二个辅助函数稍微复杂一些。
这是一组递归函数,每次调用都会消耗一个/两个元素。
首先是接地(端子)情况
void myHelper2 (std::istream &)
{ }
然后特std::string
具有以下常量的情况 char
, 分隔符(没有分隔符,如果你简单地写 is >> s
,你会得到包含在 is
中的完整字符串)
template <typename ... TS>
void myHelper2 (std::istream & is, std::string & s, char const & delim,
TS && ... ts)
{
std::getline(is, s, delim);
myHelper2(is, std::forward<TS>(ts)...);
}
接下来接收常量 char 的版本(在您的示例中为 :
、=
和 /
;但第一个用作字符串的分隔符)并丢弃 char
来自 is
(并且,如果需要,检查丢弃的字符是否是相同的参数字符)
template <typename ... TS>
void myHelper2 (std::istream & is, char const ch, TS && ... ts)
{
char ch2;
is >> ch2;
// check if `ch` == `ch2`? exception otherwise?
myHelper2(is, std::forward<TS>(ts)...);
}
最后一个一般情况,接收通用(类型 T
)引用
template <typename T, typename ... TS>
void myHelper2 (std::istream & is, T & t, TS && ... ts)
{
is >> t;
myHelper2(is, std::forward<TS>(ts)...);
}
下面是一个完整的例子。
从 C++14 开始工作,因为 std::index_sequence
和 std::index_sequence_for
在 C++14 中引入。但是如果你想要一个 C++11 解决方案,为他们写一个替代品很简单
#include <tuple>
#include <sstream>
#include <iostream>
template <typename ... TL>
struct TemplatedType
{ std::tuple<TL...> t; };
void myHelper2 (std::istream &)
{ }
template <typename ... TS>
void myHelper2 (std::istream &, char const, TS && ...);
template <typename T, typename ... TS>
void myHelper2 (std::istream &, T &, TS && ...);
template <typename ... TS>
void myHelper2 (std::istream & is, std::string & s, char const & delim,
TS && ... ts)
{
std::getline(is, s, delim);
myHelper2(is, std::forward<TS>(ts)...);
}
template <typename ... TS>
void myHelper2 (std::istream & is, char const ch, TS && ... ts)
{
char ch2;
is >> ch2;
// check if `ch` == `ch2`? exception otherwise?
myHelper2(is, std::forward<TS>(ts)...);
}
template <typename T, typename ... TS>
void myHelper2 (std::istream & is, T & t, TS && ... ts)
{
is >> t;
myHelper2(is, std::forward<TS>(ts)...);
}
template <typename ... TL, std::size_t ... IL>
void myHelper1 (std::istream & is,
TemplatedType<TL...> const & sp,
std::index_sequence<IL...> const &)
{ myHelper2(is, std::get<IL>(sp.t)...); }
template <typename ... TL>
std::istream & operator>> (std::istream & is,
TemplatedType<TL...> const & sp)
{
myHelper1(is, sp, std::index_sequence_for<TL...>{});
return is;
}
template <typename ... TL>
TemplatedType<TL...> mySplit (TL && ... al)
{ return { std::forward_as_tuple(al...) }; }
int main ()
{
std::istringstream iss("alpha:=10/50.1");
std::string x;
int y{};
double z{};
iss >> mySplit(x, ':', '=', y, '/', z);
std::cout << "- x: " << x << std::endl; // print alpha
std::cout << "- y: " << y << std::endl; // print 10
std::cout << "- z: " << z << std::endl; // print 50.1
}
关于c++ - 使用右值引用重载模板化可变参数运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49814797/
简而言之:我想从可变参数模板参数中提取各种选项,但不仅通过标签而且通过那些参数的索引,这些参数是未知的 标签。我喜欢 boost 中的方法(例如 heap 或 lockfree 策略),但想让它与 S
我可以对单元格中的 excel IF 语句提供一些帮助吗? 它在做什么? 对“BaselineAmount”进行了哪些评估? =IF(BaselineAmount, (Variance/Baselin
我正在使用以下方法: public async Task Save(Foo foo,out int param) { ....... MySqlParameter prmparamID
我正在使用 CodeGear RAD Studio IDE。 为了使用命令行参数测试我的应用程序,我多次使用了“运行 -> 参数”菜单中的“参数”字段。 但是每次我给它提供一个新值时,它都无法从“下拉
我已经为信用卡类编写了一些代码,粘贴在下面。我有一个接受上述变量的构造函数,并且正在研究一些方法将这些变量格式化为字符串,以便最终输出将类似于 号码:1234 5678 9012 3456 截止日期:
MySql IN 参数 - 在存储过程中使用时,VarChar IN 参数 val 是否需要单引号? 我已经像平常一样创建了经典 ASP 代码,但我没有更新该列。 我需要引用 VarChar 参数吗?
给出了下面的开始,但似乎不知道如何完成它。本质上,如果我调用 myTest([one, Two, Three], 2); 它应该返回元素 third。必须使用for循环来找到我的解决方案。 funct
将 1113355579999 作为参数传递时,该值在函数内部变为 959050335。 调用(main.c): printf("%d\n", FindCommonDigit(111335557999
这个问题在这里已经有了答案: Is Java "pass-by-reference" or "pass-by-value"? (92 个回答) 关闭9年前。 public class StackOve
我真的很困惑,当像 1 == scanf("%lg", &entry) 交换为 scanf("%lg", &entry) == 1 没有区别。我的实验书上说的是前者,而我觉得后者是可以理解的。 1 =
我正在尝试使用调用 SetupDiGetDeviceRegistryProperty 的函数使用德尔福 7。该调用来自示例函数 SetupEnumAvailableComPorts .它看起来像这样:
我需要在现有项目上实现一些事件的显示。我无法更改数据库结构。 在我的 Controller 中,我(从 ajax 请求)传递了一个时间戳,并且我需要显示之前的 8 个事件。因此,如果时间戳是(转换后)
rails 新手。按照多态关联的教程,我遇到了这个以在create 和destroy 中设置@client。 @client = Client.find(params[:client_id] || p
通过将 VM 参数设置为 -Xmx1024m,我能够通过 Eclipse 运行 Java 程序-Xms256M。现在我想通过 Windows 中的 .bat 文件运行相同的 Java 程序 (jar)
我有一个 Delphi DLL,它在被 Delphi 应用程序调用时工作并导出声明为的方法: Procedure ProduceOutput(request,inputs:widestring; va
浏览完文档和示例后,我还没有弄清楚 schema.yaml 文件中的参数到底用在哪里。 在此处使用 AWS 代码示例:https://github.com/aws-samples/aws-proton
程序参数: procedure get_user_profile ( i_attuid in ras_user.attuid%type, i_data_group in data_g
我有一个字符串作为参数传递给我的存储过程。 dim AgentString as String = " 'test1', 'test2', 'test3' " 我想在 IN 中使用该参数声明。 AND
这个问题已经有答案了: When should I use "this" in a class? (17 个回答) 已关闭 6 年前。 我运行了一些java代码,我看到了一些我不太明白的东西。为什么下
我输入 scroll(0,10,200,10);但是当它运行时,它会传递字符串“xxpos”或“yypos”,我确实在没有撇号的情况下尝试过,但它就是行不通。 scroll = function(xp
我是一名优秀的程序员,十分优秀!