我正在将一些代码从 Windows 移植到 MacOSX。函数模板特化存在问题。 我在 Windows 中使用 msvc14.0 和 clang5.0 成功编译了这个文件。
#include <cstring>
#include <string>
#include <iostream>
template<typename CHAR_TYPE>
size_t string_length(CHAR_TYPE text)
{
static_assert(false, "string_length is not supported this type.");
return 0;
}
template<typename CHAR_TYPE>
size_t string_length(const std::basic_string<CHAR_TYPE>& text)
{
return text.size();
}
template<>
inline size_t string_length(const char* szText)
{
return strlen(szText);
}
template<>
inline size_t string_length(const wchar_t* szwText)
{
return wcslen(szwText);
}
int main()
{
std::cout << "SZ length " << string_length("IIII") << std::endl;
std::cout << "WSZ length " << string_length(L"IIII") << std::endl;
std::cout << "string length " << string_length(std::string("IIII")) << std::endl;
std::cout << "wstring length " << string_length(std::wstring(L"IIII")) << std::endl;
}
当我在 MacOSX 中用 clang5.0 编译它时,我得到一个错误:
clang_test.cpp:9:5: error: static_assert failed "string_length is not supported
this type."
static_assert(false, "string_length is not supported this type.");
^ ~~~~~
1 error generated.
当我删除第一个函数时:
template<typename CHAR_TYPE>
size_t string_length(CHAR_TYPE text)
{
static_assert(false, "string_length is not supported this type.");
return 0;
}
我还有一些其他错误:
clang_test.cpp:19:15: error: no function template matches function template
specialization 'string_length'
inline size_t string_length(const char* szText)
^
clang_test.cpp:13:8: note: candidate template ignored: could not match 'const
basic_string<type-parameter-0-0, char_traits<type-parameter-0-0>,
allocator<type-parameter-0-0> > &' against 'const char *'
size_t string_length(const std::basic_string<CHAR_TYPE>& text)
^
clang_test.cpp:25:15: error: no function template matches function template
specialization 'string_length'
inline size_t string_length(const wchar_t* szwText)
^
clang_test.cpp:13:8: note: candidate template ignored: could not match 'const
basic_string<type-parameter-0-0, char_traits<type-parameter-0-0>,
allocator<type-parameter-0-0> > &' against 'const wchar_t *'
size_t string_length(const std::basic_string<CHAR_TYPE>& text)
^
clang_test.cpp:33:34: error: no matching function for call to 'string_length'
std::cout << "SZ length " << string_length("IIII") << std::endl;
^~~~~~~~~~~~~
clang_test.cpp:13:8: note: candidate template ignored: could not match
'basic_string<type-parameter-0-0, char_traits<type-parameter-0-0>,
allocator<type-parameter-0-0> >' against 'char const[5]'
size_t string_length(const std::basic_string<CHAR_TYPE>& text)
^
clang_test.cpp:34:35: error: no matching function for call to 'string_length'
std::cout << "WSZ length " << string_length(L"IIII") << std::endl;
^~~~~~~~~~~~~
clang_test.cpp:13:8: note: candidate template ignored: could not match
'basic_string<type-parameter-0-0, char_traits<type-parameter-0-0>,
allocator<type-parameter-0-0> >' against 'wchar_t const[5]'
size_t string_length(const std::basic_string<CHAR_TYPE>& text)
^
4 errors generated.
问题是什么?
最佳答案
即使未实例化函数,以下内容也确实是错误的:
template<typename CHAR_TYPE>
size_t string_length(CHAR_TYPE text)
{
static_assert(false, "string_length is not supported this type.");
return 0;
}
The program is ill-formed, no diagnostic required, if:
- If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.
- [..]
- a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter, or
- [..]
您可以改用(并使用重载而不是 const char*
、const wchar_t*
的特化):
template<typename CHAR_TYPE>
size_t string_length(CHAR_TYPE text) = delete;
如果您希望保留 static_assert
,则必须创建一个助手:
template <typename T> struct always_false : false_type {};
template<typename CHAR_TYPE>
size_t string_length(CHAR_TYPE text)
{
static_assert(always_false<CHAR_TYPE>::value,
"string_length is not supported this type.");
return 0;
}
关于c++ - 带有 clang 的 MacOSX 中的函数模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46886307/