c++ - 带有 clang 的 MacOSX 中的函数模板特化

标签 c++ templates

我正在将一些代码从 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;
}

temp.res/8 :

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/

相关文章:

c++ - 你如何使用映射值?

C++ 类循环引用?

c++ - 用于识别模板类中的类的元函数出现问题

html - 如何在go模板中传入map "created on the way"

c++ - 如何在模板元编程中进行小于比较?

c++ - 类型推导不适用于 std::function

c++ - 析构函数中的异常

C++ 错误 C2065 : undeclared identifier

c++ - 图像处理程序类中的 std::map 帮助

c++ - 在 C++ 11 中迭代模板类