我试图替换折叠表达式中的特定类型,同时简单地转发所有其他类型,但失败了。
As std::forward
需要显式模板专门化我尝试提供另一组模板化重载,但是这些尚未考虑重载解决方案如果这有效的话,无论如何都会导致不明确的函数调用。
第二次尝试是专门化std::forward但尝试已经失败了...
模拟std::forward
;实际上复制了 GCC 的实现,只是添加了一些输出来看看发生了什么:
namespace test
{
template<typename T>
constexpr T&&
fw(typename std::remove_reference<T>::type& t) noexcept
{
std::cout << "standard" << std::endl;
return static_cast<T&&>(t);
}
template<typename T>
constexpr T&&
fw(typename std::remove_reference<T>::type&& t) noexcept
{
std::cout << "standard (r-value)" << std::endl;
static_assert
(
!std::is_lvalue_reference<T>::value,
"template argument substituting T is an lvalue reference type"
);
return static_cast<T&&>(t);
}
}
我的测试如下:
class Test
{
public:
template <typename ... T>
void test(T&& ... t)
{
using test::fw;
///////////////////////////////////////////////////
( g(fw<T>(t)), ... );
///////////////////////////////////////////////////
}
private:
template <typename T>
T&& g(T&& t)
{
std::cout << "g: r-value: " << t << '\n' << std::endl;
return std::move(t);
}
template <typename T>
T& g(T& t)
{
std::cout << "g: l-value " << t << '\n' << std::endl;
return t;
}
};
int main()
{
int nn = 10;
Test t;
std::string s("daal");
t.test(12, nn, std::string("alda"), s);
return 0;
}
按原样(以及我失败的尝试,请参阅链接的问题)输出是:
standard
g: r-value: 12
standard
g: l-value 10
standard
g: r-value: alda
standard
g: l-value daal
所需的输出类似于:
standard
g: r-value: 12
standard
g: l-value 10
specialised (r-value)
g: r-value: alda
specialised (l-value)
g: l-value daal
(参考类型是可选的。)
我怎样才能做到这一点?
目的是保留折叠表达式 – Icould解决问题递归的模板和适当的重载,但这不是这里的目的。这是出于纯粹好奇的问题,因为我已经解决了我的实际问题(通过发现实际上根本不需要可变参数模板,因此可以使用if constexpr
相反,在函数内部,因此也不再有 XY 问题)。