簡體   English   中英

具有非類型參數包的模糊類模板實例化

[英]Ambiguous class template instantiation with nontype parameter packs

我正在嘗試專門研究Expr

#include <tuple>
#include <type_traits>
#include <iostream>

template<class Tp, class List> 
struct Expr {
    Expr(){std::cout << "0"<< std::endl;};
};

//specialization #1
template<class Tp, int...i>
struct Expr<Tp,std::tuple<std::integral_constant<int,i>...>> {

    Expr(){std::cout << "1"<< std::endl;};
};

//specialization #2
template<int...i>
struct Expr<double,std::tuple<std::integral_constant<int,i>...>> {

    Expr(){std::cout << "2"<< std::endl;};
};

int main() {

    typedef std::tuple<std::integral_constant<int,1>> mylist;

    Expr<double,mylist> test{};

    return 0;
}

但是,出現以下編譯器錯誤:

[x86-64 gcc 6.3] error: ambiguous template instantiation for 'struct Expr<double, std::tuple<std::integral_constant<int, 1> > >'
[x86-64 gcc 6.3] error: variable 'Expr<double, std::tuple<std::integral_constant<int, 1> > > test' has initializer but incomplete type

在這里,尤其是第一個錯誤困擾着我。 我試圖弄清楚為什么這是一個模棱兩可的實例。

編譯器不應該選擇specialization #2嗎?

如果我避免將非類型參數包int...i包裝在std::integral_constant則可以毫無問題地進行編譯,並選擇第二種特殊化方法。 以下示例起作用:

#include <tuple>
#include <type_traits>
#include <iostream>

template<class Tp, class List> 
struct Expr {
    Expr(){std::cout << "0"<< std::endl;};
};

//specialization #1
template<class Tp, class...args>
struct Expr<Tp,std::tuple<args...>> {

    Expr(){std::cout << "1"<< std::endl;};
};

//specialization #2
template<class...args>
struct Expr<double,std::tuple<args...>> {

    Expr(){std::cout << "2"<< std::endl;};
};

int main() {

    typedef std::tuple<std::integral_constant<int,1>> mylist;

    Expr<double,mylist> test{};

    return 0;
}

那是不對的。 這是一個gcc錯誤(我找不到錯誤報告,也許還沒有報告?)。

沒錯,必須選擇專業化#2。 因為有兩個匹配的特殊化,所以偏序選擇最特殊的一個,在您的情況下為#2(作為第一個參數的double精度比任何類型的第一個參數更特殊)。

此外,clang可以毫無問題地編譯您的代碼。

暫無
暫無

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

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