[英]c++ : how to remove cv-qualifiers of a type to access class functions?
這里有一個例子:
#include <iostream>
template<typename T,
typename ... Args>
void print(T&& t, Args&& ... args)
{
// line where compilation fails when the A::run is called
if constexpr (std::is_invocable_v<decltype(&T::display),T*,Args...>)
{
t.display(std::forward<Args>(args)...);
}
else
{
std::cout << "not applicable !" << std::endl;
}
}
template<typename T>
class A
{
public:
A(T&& t):t_(t){}
template <typename... Args>
void run(Args&& ... args)
{
print<T,Args...>(t_,std::forward<Args>(args)...);
}
T t_;
};
template <typename T> A(T&) -> A<T&>;
template <typename T> A(T&&) -> A<T>;
class B
{
public:
B(int value):value_(value){}
void display(int a, int b)
{
std::cout << value_ << " "
<< a << " "
<< b << std::endl;
}
int value_;
};
int main()
{
int v1=10;
int v2=20;
B b1{1};
A a1{b1};
a1.t_.display(v1,v2);
A a2{B(2)};
a2.t_.display(v1,v2);
//a1.run(v1,v2); // (1)
//a2.run(v1,v2); // (2)
//a1.run(v1);
return 0;
}
上面的代碼編譯並運行良好。 但是如果最后 3 行(調用run()
)沒有注釋,則會發生以下編譯錯誤:
(1)
main.cpp:7:48: 錯誤:'display' 不是 'B&' 的成員
if constexpr (std::is_invocable_v<decltype(&T::display),T*,Args...>)
(2)
main.cpp:27:25: 錯誤:沒有匹配的函數來調用'print(B&, int&, int&)'
print<T,Args...>(t_,std::forward<Args>(args)...);
筆記 :
template <typename T> A(T&) -> A<T&>;
template <typename T> A(T&&) -> A<T>;
在這里解釋:
問題(1)和(2)是不同的問題。
問題 (1) 來自以下std::is_invocable_v
template<typename T,
typename ... Args>
void print(T&& t, Args&& ... args)
{
if constexpr (std::is_invocable_v<decltype(&T::display),T*,Args...>)
// no T but std::decay_t<T> ...............^...........^
而不是T
(可以作為參考),您需要“腐朽”類型
我提議
template <typename T, typename ... Args>
void print (T && t, Args && ... args)
{
using U = std::decay_t<T>;
if constexpr ( std::is_invocable_v<decltype(&U::display), U*, Args...> )
t.display(std::forward<Args>(args)...);
else
std::cout << "not applicable !" << std::endl;
}
問題 (2) 來自以下事實,即在以下print()
調用中解釋模板參數
template <typename... Args>
void run(Args&& ... args)
{
print<T,Args...>(t_,std::forward<Args>(args)...);
}
你阻礙了正確的模板推斷。
建議:讓模板演繹,完美轉發,工作和調用函數如下
print(t_,std::forward<Args>(args)...);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.