如何修复 "array rvalue" 不使用 gcc-4.8 和 clang-3.7 编译?
How to fix "array rvalue" not compiling with gcc-4.8 and clang-3.7?
此代码段至少需要标记 -std=c++Ox
才能使用 GCC-4.9 进行编译。
请参阅 online compilation on gcc.godbolt.org。
template <typename T, int SIZE>
int foo (const T (&table) [SIZE]) // T = char
{
return SIZE ? table[0] : 0;
}
template <typename T, int SIZE>
int bar (const T (&table) [SIZE]) // T = char *
{
return SIZE ? table[0][0] : 0;
}
int main (int argc, char *argv[])
{
return argc
+ foo( "foo" )
+ foo( {argv[0][0], argv[1][1]} ) // array rvalue
+ bar( {argv[0], argv[1] } ); // array rvalue
}
使用 GCC-4.9 ... GCC-6 可以很好地编译。
但无法使用以前的 GCC 版本和所有 Clang 版本(最后测试的是 Clang-3.7.1)。
问题
- 如何更改以解决此问题?
(如果可能,只调整 main()
正文)
- 有没有办法使代码与 C++03 兼容?
(同样,如果可能,只在 main()
正文中)
GCC-4.8.2 输出
example.cpp: In function 'int main(int, char**)':
17 : error: no matching function for call to 'foo(<brace-enclosed initializer list>)'
+ foo( { argv[0][0], argv[1][1] } )
^
17 : note: candidate is:
2 : note: template<class T, int SIZE> int foo(const T (&)[SIZE])
int foo (const T (&table) [SIZE]) // T = char
^
2 : note: template argument deduction/substitution failed:
17 : note: couldn't deduce template parameter 'T'
+ foo( { argv[0][0], argv[1][1] } )
^
18 : error: no matching function for call to 'bar(<brace-enclosed initializer list>)'
+ bar( { argv[0], argv[1] } );
^
18 : note: candidate is:
8 : note: template<class T, int SIZE> int bar(const T (&)[SIZE])
int bar (const T (&table) [SIZE]) // T = char *
^
8 : note: template argument deduction/substitution failed:
18 : note: couldn't deduce template parameter 'T'
+ bar( { argv[0], argv[1] } );
^
Compilation failed
Clang-3.7.1 输出
17 : error: no matching function for call to 'foo'
+ foo( { argv[0][0], argv[1][1] } )
^~~
2 : note: candidate template ignored: couldn't infer template argument 'T'
int foo (const T (&table) [SIZE]) // T = char
^
18 : error: no matching function for call to 'bar'
+ bar( { argv[0], argv[1] } );
^~~
8 : note: candidate template ignored: couldn't infer template argument 'T'
int bar (const T (&table) [SIZE]) // T = char *
^
2 errors generated.
Compilation failed
您可以通过为 C++11 将创建的临时数组命名来使此代码与 C++03 兼容。
int main (int argc, char *argv[])
{
const char il1[] = {argv[0][0], argv[1][1]};
const char* const il2[] = { argv[0], argv[1] };
return argc
+ foo( "foo" )
+ foo( il1 )
+ bar( il2 );
}
此代码段至少需要标记 -std=c++Ox
才能使用 GCC-4.9 进行编译。
请参阅 online compilation on gcc.godbolt.org。
template <typename T, int SIZE>
int foo (const T (&table) [SIZE]) // T = char
{
return SIZE ? table[0] : 0;
}
template <typename T, int SIZE>
int bar (const T (&table) [SIZE]) // T = char *
{
return SIZE ? table[0][0] : 0;
}
int main (int argc, char *argv[])
{
return argc
+ foo( "foo" )
+ foo( {argv[0][0], argv[1][1]} ) // array rvalue
+ bar( {argv[0], argv[1] } ); // array rvalue
}
使用 GCC-4.9 ... GCC-6 可以很好地编译。
但无法使用以前的 GCC 版本和所有 Clang 版本(最后测试的是 Clang-3.7.1)。
问题
- 如何更改以解决此问题?
(如果可能,只调整main()
正文) - 有没有办法使代码与 C++03 兼容?
(同样,如果可能,只在main()
正文中)
GCC-4.8.2 输出
example.cpp: In function 'int main(int, char**)':
17 : error: no matching function for call to 'foo(<brace-enclosed initializer list>)'
+ foo( { argv[0][0], argv[1][1] } )
^
17 : note: candidate is:
2 : note: template<class T, int SIZE> int foo(const T (&)[SIZE])
int foo (const T (&table) [SIZE]) // T = char
^
2 : note: template argument deduction/substitution failed:
17 : note: couldn't deduce template parameter 'T'
+ foo( { argv[0][0], argv[1][1] } )
^
18 : error: no matching function for call to 'bar(<brace-enclosed initializer list>)'
+ bar( { argv[0], argv[1] } );
^
18 : note: candidate is:
8 : note: template<class T, int SIZE> int bar(const T (&)[SIZE])
int bar (const T (&table) [SIZE]) // T = char *
^
8 : note: template argument deduction/substitution failed:
18 : note: couldn't deduce template parameter 'T'
+ bar( { argv[0], argv[1] } );
^
Compilation failed
Clang-3.7.1 输出
17 : error: no matching function for call to 'foo'
+ foo( { argv[0][0], argv[1][1] } )
^~~
2 : note: candidate template ignored: couldn't infer template argument 'T'
int foo (const T (&table) [SIZE]) // T = char
^
18 : error: no matching function for call to 'bar'
+ bar( { argv[0], argv[1] } );
^~~
8 : note: candidate template ignored: couldn't infer template argument 'T'
int bar (const T (&table) [SIZE]) // T = char *
^
2 errors generated.
Compilation failed
您可以通过为 C++11 将创建的临时数组命名来使此代码与 C++03 兼容。
int main (int argc, char *argv[])
{
const char il1[] = {argv[0][0], argv[1][1]};
const char* const il2[] = { argv[0], argv[1] };
return argc
+ foo( "foo" )
+ foo( il1 )
+ bar( il2 );
}