C++ c++;:如何删除类型的cv限定符以访问类函数?
这里有一个例子:C++ c++;:如何删除类型的cv限定符以访问类函数?,c++,template-meta-programming,constexpr,move-semantics,perfect-forwarding,C++,Template Meta Programming,Constexpr,Move Semantics,Perfect Forwarding,这里有一个例子: #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<de
#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;
}
(二)
main.cpp:27:25:错误:调用“print(B&,int&,int&)”时没有匹配函数
print(t_,std::forward问题(1)和(2)是不同的问题
问题(1)来自以下事实:在以下std::is\u invocable\u 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> ...............^...........^
问题(2)来自以下事实:在下面的print()
调用中解释模板参数
template <typename... Args>
void run(Args&& ... args)
{
print<T,Args...>(t_,std::forward<Args>(args)...);
}
模板
无效运行(Args&…Args)
{
打印(t_,std::forward(args)…);
}
您妨碍了正确的模板推断
建议:让模板演绎,完善转发,工作和调用功能如下
print(t_,std::forward<Args>(args)...);
print(t_,std::forward(args)…);
std::decay\u t
工作正常,@rafix07我很困惑,这确实为我解决了(2)(c++17):@rafix07实际上它在我的机器gcc 7.4上工作。我想知道为什么它不能在gdb Onlinet上工作。对于(2),虽然我可以理解模板推断可能更明智,但我仍然不明白为什么打印不能compile@Vince-不确定,但是…当您声明a2
时,参数是aB&
,所以(演绎指南)a2
变成a
;所以T
是B
;调用print()
解释T
,你说print()
中的T
类型是B
;但是print()
中的T
类型是T&
,所以变成B&
;但是你转到print()
t
成员;因此将B&
传递给等待aB&
的函数。
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> ...............^...........^
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;
}
template <typename... Args>
void run(Args&& ... args)
{
print<T,Args...>(t_,std::forward<Args>(args)...);
}
print(t_,std::forward<Args>(args)...);