我有兩個可變參數構造一個結構,在該第二個的前面由單個int const*
參數的存在來區分:參數包列表膨脹引起可變參數構造函數重載失敗
struct S
{
template<class... Args> S(Args... args)
{
int arr[sizeof...(args)] = { args... }; // [A]
}
template<class... Args> S(int const *p, Args... args) {} // [B]
};
int main()
{
int i = 1;
S s(&i, 1, 2); // [C]
return 0;
}
使用Visual C++ 2015 ,行[A]導致:error C2440: 'initializing': cannot convert from 'int *' to 'int'
。如果我註釋掉[A]行,那麼它會編譯好的和[C]的調用[B],所以看起來初始化程序列表的存在會導致編譯器查看函數內部並變得貪婪,以嘗試將所有爭論列表轉換爲int
,忽略解釋[B]。
如果我繼續[A],但改變[C],以S s((int const*)&i, 1, 2);
構造函數調用,然後它也編譯好了,[A]似乎防止int*
隱式轉換爲int const*
通常適用於常規功能。
如果我不想在所有構造函數調用中顯式地使用const轉換指針,而不是使用行[A],我可以使用遞歸函數將參數包解壓縮到int數組中,但這更加混亂。最簡單的解決方案就是將[B]更改爲template<class... Args> S(int *p, Args... args) {}
,但那麼隱藏我的意圖不會被更改爲*p
。
你可以讓'int i'爲'constexpr int i'嗎? – AndyG
我可以將此示例更改爲'int const i = 1',它可以工作,但通常情況下,我並不總是傳遞一個int const的地址,通常是傳遞一個數組。 –