4
我試圖專注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;
}