[英]add_const won't work with forwarding references
我將add_const
類型特征應用於轉發引用類型時使用它。 一切看起來都沒有添加PrintType
,因此我舉了一個小例子來驗證這種情況( PrintType
是不完整的類型,它將導致編譯錯誤,從而迫使編譯器在錯誤中吐出模板參數的名稱信息) :
#include <iostream>
#include <type_traits>
#include <complex>
template <class T>
struct PrintType;
template <class T>
void f(T&& arg)
{
PrintType<std::add_const_t<decltype(arg)>> local;
(void)local;
}
int main()
{
std::complex<double> co;
f(co);
}
該錯誤消息說 :
main.cpp: In instantiation of 'void f(T&&) [with T = std::complex<double>&]':
main.cpp:20:9: required from here
main.cpp:12:48: error: 'PrintType<std::complex<double>&> local' has incomplete type
PrintType<std::add_const_t<decltype(arg)>> local;
即特征將我的類型轉換為T = std::complex<double>&
而不是T = std::complex<double> const&
類型特征按預期工作。 您應該考慮要嘗試做的事情,這就是將常量添加到引用中。 您不能重新綁定引用 (它是不可變的),因此基本上任何引用都是const
引用
T& == T& const
我想你希望做的是創造一個const類型的引用(這讓我想起的const iterator
VS const_iterator
啄)的俊男來實現這種方式,你不能引用類型的typedef一個同樣的原因以這種方式引用const類型 :
typedef T& ref_t;
typedef const ref_t const_ref_t; // This is not T const& !!
綜上所述,將const添加到引用類型會使它成為const引用(與引用相同),而不是對const
類型的引用
對於此類情況,具有將引用轉換為新類型的類型特征可能會很有用。 這可以補充對const
和volatile
所做的相同操作的另一個特性,實現方式幾乎相同。 在你的情況,你應該只需要擔心左值引用如果你使用T
,而不是decltype(arg)
但是,如果使用lambda,則確實確實需要擔心右值引用。
這是一個示例實現:
template<typename T, bool ApplyLvalueRef, bool ApplyRvalueRef>
struct apply_ref {
static_assert(!(ApplyLvalueRef && ApplyRvalueRef), "Improper use: T cannot be & and &&");
using possibly_lref = std::conditional_t<
ApplyLvalueRef,
std::add_lvalue_reference_t<T>,
T
>;
using type = std::conditional_t<
ApplyRvalueRef,
std::add_rvalue_reference_t<possibly_lref>,
possibly_lref
>;
};
template<typename From, typename To>
struct transfer_ref : apply_ref<To, std::is_lvalue_reference<From>{}, std::is_rvalue_reference<From>{}> {};
template<typename From, typename To>
using transfer_ref_t = typename transfer_ref<From, To>::type;
乍一看,為左值與右值使用單獨的布爾值似乎有點可笑。 但是,這兩者都不適用。 絕對不應存在兩種情況都成立的情況,而這是由靜態斷言強制執行的。
現在我們可以輕松地編寫函數:
template <class T>
void f(T&& arg)
{
using with_const = std::add_const_t<std::remove_reference_t<T>>;
PrintType<transfer_ref_t<T, with_const>> local;
(void)local;
}
由於我們不能將const
應用於引用,因此必須將其剝離,將const
添加到所引用的類型,然后再添加引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.