是否可以在不使用 SFINAE 或编写多个版本的情况下完美转发"non-generic"类型?
Is it possible to perfectly forward a "non-generic" type without using SFINAE or writing multiple versions?
我了解完美转发在通常情况下是如何工作的:
template <typename T>
void f(T &&arg) {
E(std::forward<T>(arg)));
}
在不使用SFINAE或编写多个版本的情况下,是否可以完美地转发"非泛型"类型,例如某种形式的std::string
?
/* Likely some kind of template. */
/* template <typename T> */
void f(/* Something goes here*/ arg) {
E(std::forward</* Something goes here. */>(arg);
}
以下内容应为真:
f(std_str_obj); // Lvalue forwarded as const lvalue ref.
f("hello"); // Temporary forwarded as rvalue reference.
f(1); // Error, not a std::string or convertible to std::string.
我怀疑唯一的方法是仍然编写一个函数模板,并使用某种形式的SFINAE来限制它(在这种情况下,我可以自己解决一些问题(,但我想知道是否有一些简单的方法我遗漏了。
不,这样的事情是不可能的。
如果你的函数只采用一种指定的类型,最好只创建两个函数,不要试图用技巧巧妙地使用语言。
如果使用template,则f(1);
将int设置为模板参数。这不是你想要的。
除非我遗漏了什么,否则这应该适用于您正在寻找的内容。
void f(std::string&& arg) // Take care of rvalues
{
E(std::forward<std::string&&>(arg));
}
void f(std::string const& arg) // Take care of lvalues
{
E(std::forward<std::string const&>(arg));
}
我能够使用以下程序进行测试:
#include <iostream>
#include <string>
#include <utility>
void E(std::string const& s)
{
std::cout << "Came to E(std::string const& )n";
}
void E(std::string&& s)
{
std::cout << "Came to E(std::string&& )n";
}
void f(std::string&& arg) // Take care of rvalues
{
E(std::forward<std::string&&>(arg));
}
void f(std::string const& arg) // Take care of lvalues
{
E(std::forward<std::string const&>(arg));
}
int main()
{
std::string s1("abcd");
f(s1);
f("xyx");
}
我从运行程序中得到的输出:
到达E(std::string const&(来到E(std::string&&(
更新
用函数模板替换f
的两个重载实现也同样有效。
template <typename T>
void f(T&& arg)
{
E(std::forward<T>(arg));
}
int main()
{
std::string s1("abcd");
f(s1);
f("xyx");
}
如果我将f(1)
添加到main
,则会出现编译器错误,因为E
没有重载可以使用它。如果E
本身是一个函数模板,那么该策略将不起作用。
我认为,底线是,你必须阻止使用std::string
以外的任何东西,因为你不能在f
或E
级别上处理这些类型。
#include <utility>
#include <type_traits>
template <
class T
, class = typename std::enable_if<
std::is_convertible<std::decay_t<T>, std::string const&>::value
|| std::is_convertible<std::decay_t<T>, std::string &&>::value
>::type
>
void f (T&& t) { E (std::forward<T> (t)); }
相关文章:
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 有没有办法在不使用 #ifdef 的情况下不编译发布版本中的单元测试函数体?
- 如何在没有 nvcc 的情况下在编译时获取 CUDA 工具包版本?
- 在同一系统上有多个GCC的情况下,使用哪个版本的libstdc++.so
- PDB无法显示发布版本崩溃的确切行号,但在二进制调试版本的情况下显示精确行号
- 在没有第三方工具/项目的情况下,在 MFC C++发布版本中查找内存泄漏
- 有没有一种方法可以在不下载整个文件的情况下确定托管在HTTP服务器上的文件的版本?
- 在c++ 11或更高版本中,是否有一种方法可以让constexpr在没有UB的情况下确定endian ?
- 是否可以在不使用 SFINAE 或编写多个版本的情况下完美转发"non-generic"类型?
- 有没有办法在不修改新版本的情况下(暂时)恢复旧的G++3.2版本