這個問題在這里已經有了答案: SFINAE: std::enable_if 作為函式引數 2答案 7 天前關閉。
最小的例子很短:
#include <iostream>
#include <array>
#include <type_traits>
struct Foo{
//template <class C>
//Foo(C col, typename std::enable_if<true,C>::type* = 0){
// std::cout << "optional argument constructor works" << std::endl;
//}
template <class C>
Foo(typename std::enable_if<true, C>::type col){
std::cout << "no optional argument constructor works NOT" << std::endl;
}
};
int main()
{
auto foo = Foo(std::array<bool,3>{0,0,1});
}
第一個建構式按預期作業。但是第二個建構式沒有編譯,我得到
錯誤:沒有用于呼叫 'Foo::Foo(std::array)' 的匹配函式
但是給出的解釋
注意:模板引數扣除/替換失敗
沒有幫助,std::enable_if<true, C>::type應該是C這樣,兩個建構式中的第一個引數對編譯器來說應該看起來完全相同。我顯然錯過了一些東西。為什么編譯器的行為不同,對于不使用可選引數的建構式和 enable_if 是否還有其他解決方案?
完整的錯誤資訊:
main.cpp:18:45: error: no matching function for call to ‘Foo::Foo(std::array)’
18 | auto foo = Foo(std::array<bool,3>{0,0,1});
| ^
main.cpp:11:5: note: candidate: ‘template Foo::Foo(typename std::enable_if::type)’
11 | Foo(typename std::enable_if<true, C>::type col){
| ^~~
main.cpp:11:5: note: template argument deduction/substitution failed:
main.cpp:18:45: note: couldn’t deduce template parameter ‘C’
18 | auto foo = Foo(std::array<bool,3>{0,0,1});
| ^
main.cpp:5:8: note: candidate: ‘constexpr Foo::Foo(const Foo&)’
5 | struct Foo{
| ^~~
main.cpp:5:8: note: no known conversion for argument 1 from ‘std::array’ to ‘const Foo&’
main.cpp:5:8: note: candidate: ‘constexpr Foo::Foo(Foo&&)’
main.cpp:5:8: note: no known conversion for argument 1 from ‘std::array’ to ‘Foo&&’
uj5u.com熱心網友回復:
模板引數推導不能以這種方式作業。
假設您有一個模板和一個使用該模板的型別別名的函式:
template <typename T>
struct foo;
template <typename S>
void bar(foo<S>::type x) {}
例如,當您呼叫該函式時,foo(1)編譯器將不會嘗試所有實體化 offoo來查看是否有type與 的型別匹配的a 1。它不能這樣做,因為foo::type不一定是明確的。可能是不同的實體具有相同的foo<T>::type:
template <>
struct foo<int> { using type = int; };
template <>
struct foo<double> { using type = int; };
甚至沒有嘗試這條路線并可能導致歧義,foo<S>::type x而是一個非推斷的背景關系。有關詳細資訊,請參閱什么是非演繹背景關系?.
uj5u.com熱心網友回復:
模板引數推導失敗,因為C出現在Non-deduced context 中。鏈接頁面串列
使用限定 ID 指定的型別的嵌套名稱說明符(范圍決議運算子 :: 左側的所有內容)
作為非推斷背景關系。
他們還提到了另一個例子:
例如, in
A<T>::B<T2>,T由于規則 #1(嵌套名稱說明符)而不是推導,并且T2是非推導,因為它是相同型別名稱的一部分,但是 invoid(*f)(typename A<T>::B, A<T>),TinA<T>::B是非推導的(因為相同的規則),而TinA<T>被推匯出來。
uj5u.com熱心網友回復:
其他答案已經解釋了為什么論證推導在這里不起作用。如果你想要enable_if你的建構式,你可以簡單地將條件放在模板串列中,如下所示:
struct Foo{
// your condition here ---v
template <class C, typename std::enable_if_t< true >* = nullptr>
Foo(C col) {
std::cout << "constructor" << std::endl;
}
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/473695.html
上一篇:從類方法回傳結構指標
下一篇:在運行時更改模板型別
