簡體   English   中英

不會調用模板化構造函數的專用模板

[英]Specialized template of a templated constructor does not get invoked

我試圖模仿可繼承構造函數的行為,因為它們還沒有用g ++實現。

我嘗試了這里描述的技術https://stackoverflow.com/a/5411992/234261但是當我想添加自己的構造函數時,我遇到了問題。 具體來說,我試圖添加一個專門的復制構造函數,以及繼承所有其他構造函數。 不幸的是,總是調用繼承的,更通用的復制構造函數。

一個例子

#include <iostream>
struct A {
  A(){}
  A(const A &){ std::cout << "IN A" << std::endl; }
};

struct B : public A{
  template<typename ...Args,
           typename = typename std::enable_if
      <
             std::is_constructible<A, Args...>::value
             >::type>
  B(Args &&...args)
    : A(std::forward<Args>(args)...) {}

  // These don't work either.                                                                                                                
  //B(const A &a):A(a){ std::cout << "IN B-A" << std::endl; }                                                                                
  //B(const B &b):A(b){ std::cout << "IN B-B" << std::endl; }                                                                                
};
template<>
B::B(const A &a):A(a){ std::cout << "IN B-A" << std::endl; }
template<>
B::B(const B &b):A(b){ std::cout << "IN B-B" << std::endl; }

int main(){
  A a;      // 1. Prints nothing as expected                                                                                                    
  B b(a);   // 2. Prints "IN A" only                                                                                                              
  B b1(b);  // 3. Prints "IN A" only                                                                                                              
  return 0;
}

我想[3]打印IN A然后打印IN BB 不知何故,我設法讓[2]在我的實際代碼中工作,但由於某種原因不能在這個小例子中重復它。

我知道正在創建模板構造函數是因為子類(B)實際上可以用於構造超類(A)。

但是,為什么我的顯式專業化不會被調用? 我的專業不正確嗎? 有沒有更好的辦法?


如果有人想運行它,請鏈接到此示例http://ideone.com/eUHD5

我正在使用gcc 4.6

以下“作品”:

struct B : public A
{
    template<typename ...Args, typename = typename std::enable_if<std::is_constructible<A, Args...>::value>::type>
    B(Args &&...args) : A(std::forward<Args>(args)...) {}

    B(const A & a) : A(a){ std::cout << "IN B-A" << std::endl; }
    B(const B & b) : A(b){ std::cout << "IN B-B" << std::endl; }
};


int main()
{
    A a;
    B b(a);
    B b1(static_cast<B const &>(b)); 
}

這是舊的模板 - 過載 - 是一個更好的匹配板栗。 請參閱STL的講座#3 ,以獲得深入的解釋。 基本上,將b綁定到推斷模板參數Args... = { B }的引用完全匹配身份,同時將其綁定到B const &需要限定符轉換,這是身份轉換的嚴格超集。

通過顯式轉換為const-reference,模板化和非模板構造函數現在都是完美匹配,但作為非模板是關系。

這將無需將內容轉換為const即可工作:

#include <iostream>
struct A {
  A(){}
  A(const A &){ std::cout << "IN A" << std::endl; }
};

struct B : public A{
  B() = default;

  template<typename A0, typename ...Args,
           typename = typename std::enable_if
      <
             !std::is_same<typename std::decay<A0>::type, A>::value &&
             !std::is_same<typename std::decay<A0>::type, B>::value &&
             std::is_constructible<A, A0, Args...>::value
             >::type>
  B(A0&& a0, Args &&...args)
    : A(std::forward<A0>(a0), std::forward<Args>(args)...) {}

  B(const A &a):A(a){ std::cout << "IN B-A" << std::endl; }                                                                                
  B(const B &b):A(b){ std::cout << "IN B-B" << std::endl; }                                                                                
};

int main(){
  A a;      // 1. Prints nothing as expected                                                                                                    
  B b(a);   // 2. Prints "IN A" only                                                                                                              
  B b1(b);  // 3. Prints "IN A" only                                                                                                              
  return 0;
}

雖然對作者來說比較麻煩,但對客戶來說更干凈。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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