簡體   English   中英

C++:如何刪除類型的 cv 限定符以訪問類函數?

[英]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>;

在這里解釋:

c++類同居的copy(reference)構造函數和move構造函數

問題(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM