EricWF created this revision. This patch fixes http://llvm.org/PR31938. The description below is copy/pasted from the bug:
The standard says: template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>> class basic_string { using value_type = typename traits::char_type; // ... basic_string(const charT* s, const Allocator& a = Allocator()); }; libc++ actually chooses to declare the constructor as basic_string(const value_type* s, const Allocator& a = Allocator()); The implicit deduction guides from class template argument deduction make what was previously an implementation detail visible: std::basic_string s = "foo"; // error, can't deduce charT. The constructor in question is in the libc++ DSO, but fortunately it looks like fixing this will not result in an ABI break. @rsmith How does this look? I did more than just the constructors mentioned in the PR, but IDK how far to take it. https://reviews.llvm.org/D29863 Files: include/string test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp
Index: test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp =================================================================== --- /dev/null +++ test/std/strings/basic.string/string.cons/implicit_deduction_guides.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// Clang does not implement deduction guides yet. +// XFAIL: clang, apple-clang + +// <string> + +// Test that the constructors offered by std::basic_string are formulated +// so they're compatible with implicit deduction guides. + +#include <string> +#include <cassert> + +#include "test_macros.h" +#include "test_allocator.h" + + +template <class T, class Alloc = std::allocator<T>> +using BStr = std::basic_string<T, std::char_traits<T>, Alloc>; + + +int main() +{ + { + std::basic_string s = "hello world"; + std::basic_string w(L"hello world"); + + ASSERT_SAME_TYPE(decltype(s), std::basic_string<char>); + ASSERT_SAME_TYPE(decltype(w), std::basic_string<wchar_t>); + } + { + std::basic_string s("hello world", test_allocator<char>{}); + ASSERT_SAME_TYPE(decltype(s), BStr<char, test_allocator<char>>); + } + { + std::basic_string s("hello world", 2ull, test_allocator<char>{}); + std::basic_string w(L"hello world", 2ull, test_allocator<wchar_t>{}); + ASSERT_SAME_TYPE(decltype(s), BStr<char,test_allocator<char>>); + ASSERT_SAME_TYPE(decltype(w), BStr<wchar_t, test_allocator<wchar_t>>); + + } + { + std::string const s1; + std::basic_string s(s1); + ASSERT_SAME_TYPE(decltype(s), std::string); + + std::basic_string w = std::wstring{}; + ASSERT_SAME_TYPE(decltype(w), std::wstring); + } +} Index: include/string =================================================================== --- include/string +++ include/string @@ -775,13 +775,13 @@ _LIBCPP_INLINE_VISIBILITY basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s); + _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s); _LIBCPP_INLINE_VISIBILITY - basic_string(const value_type* __s, const allocator_type& __a); + basic_string(const _CharT* __s, const _Allocator& __a); _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s, size_type __n); _LIBCPP_INLINE_VISIBILITY - basic_string(const value_type* __s, size_type __n, const allocator_type& __a); + basic_string(const _CharT* __s, size_type __n, const _Allocator& __a); _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, value_type __c); _LIBCPP_INLINE_VISIBILITY @@ -1557,7 +1557,7 @@ template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s) +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); __init(__s, traits_type::length(__s)); @@ -1568,7 +1568,7 @@ template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a) +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) : __r_(__a) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); @@ -1591,7 +1591,7 @@ template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a) +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) : __r_(__a) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits