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
时,参数是a
B&
,所以(演绎指南)
a2
变成
a
;所以
T
B
;调用
print()
解释
T
,你说
print()
中的
T
类型是
B
;但是
print()
中的
T
类型是
T&
,所以变成
B&
;但是你转到
print()
t
成员;因此将
B&
传递给等待a
B&
的函数。
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)...);