I want to declare my 2D vector first, then give it a size.
But why I am getting error?
Can anyone explain me?
int main() {
vector<vector<int>> a;
a = vector<int>(16, vector<int>(15));
cout << a.size() << a[0].size();
}
The reason for doing it is that I don't know the size before but after getting the input from the user, I want to give it the size.
Error:
Char 9: error: no matching constructor for initialization of 'vector<int>'
a = vector<int>(16, vector<int>(15));
^ ~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:507:7: note: candidate constructor not viable: no known conversion from 'vector<int>' to 'const std::vector<int, std::allocator<int>>::allocator_type' (aka 'const std::allocator<int>') for 2nd argument
vector(size_type __n, const allocator_type& __a = allocator_type())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:519:7: note: candidate constructor not viable: no known conversion from 'vector<int>' to 'const std::vector<int, std::allocator<int>>::value_type' (aka 'const int') for 2nd argument
vector(size_type __n, const value_type& __value,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:572:7: note: candidate constructor not viable: no known conversion from 'int' to 'const std::vector<int, std::allocator<int>>' for 1st argument
vector(const vector& __x, const allocator_type& __a)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:604:7: note: candidate constructor not viable: no known conversion from 'int' to 'std::vector<int, std::allocator<int>>' for 1st argument
vector(vector&& __rv, const allocator_type& __m)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:622:7: note: candidate constructor not viable: no known conversion from 'int' to 'initializer_list<std::vector<int, std::allocator<int>>::value_type>' (aka 'initializer_list<int>') for 1st argument
vector(initializer_list<value_type> __l,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:650:2: note: candidate template ignored: deduced conflicting types for parameter '_InputIterator' ('int' vs. 'std::vector<int, std::allocator<int>>')
vector(_InputIterator __first, _InputIterator __last,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:494:7: note: candidate constructor not viable: requires single argument '__a', but 2 arguments were provided
vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:550:7: note: candidate constructor not viable: requires single argument '__x', but 2 arguments were provided
vector(const vector& __x)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:569:7: note: candidate constructor not viable: requires 1 argument, but 2 were provided
vector(vector&&) noexcept = default;
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:582:7: note: candidate constructor not viable: requires 3 arguments, but 2 were provided
vector(vector&& __rv, const allocator_type& __m, true_type) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:586:7: note: candidate constructor not viable: requires 3 arguments, but 2 were provided
vector(vector&& __rv, const allocator_type& __m, false_type)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:484:7: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
vector() = default;
^
1 error generated.
vector<int> is not a 2D vector.
Instead of this:
a = vector<int>(16, vector<int>(15));
You should use this:
a = vector<vector<int>>(16, vector<int>(15));
I have this c++ program with the following types:
typedef pcl::PointXYZI PointType;
typedef pcl::PointCloud<PointType> PointCloudType;
typedef std::vector<PointCloudType::Ptr> CloudPtrList;
and this in main:
CloudPtrList clusterPtr(2);
for (int i = 0; i < clusterPtr.size(); ++i)
{
clusterPtr[i] = boost::make_shared<PointCloudType>();
}
And i keep getting this error ' no viable overloaded =' when i try to initialize this vector (the for above)
clusterPtr[i] = boost::make_shared<PointCloudType>();
This is the full error:
No viable overloaded '='
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3737:17: Candidate function not viable: no known conversion from 'typename boost::detail::sp_if_not_array<PointCloud<PointXYZI> >::type' (aka 'shared_ptr<pcl::PointCloud<pcl::PointXYZI> >') to 'const std::__1::shared_ptr<pcl::PointCloud<pcl::PointXYZI> >' for 1st argument
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3748:17: Candidate function not viable: no known conversion from 'typename boost::detail::sp_if_not_array<PointCloud<PointXYZI> >::type' (aka 'shared_ptr<pcl::PointCloud<pcl::PointXYZI> >') to 'std::__1::shared_ptr<pcl::PointCloud<pcl::PointXYZI> >' for 1st argument
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3745:9: Candidate template ignored: could not match 'std::__1::shared_ptr' against 'boost::shared_ptr'
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3756:9: Candidate template ignored: could not match 'std::__1::shared_ptr' against 'boost::shared_ptr'
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3766:9: Candidate template ignored: could not match 'auto_ptr' against 'shared_ptr'
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3790:9: Candidate template ignored: could not match 'unique_ptr' against 'shared_ptr'
As can be seen in the error message ...
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3737:17: Candidate function not viable: no known conversion from 'typename boost::detail::sp_if_not_array<PointCloud<PointXYZI> >::type' (aka 'shared_ptr<pcl::PointCloud<pcl::PointXYZI> >') to 'const std::__1::shared_ptr<pcl::PointCloud<pcl::PointXYZI> >' for 1st argument
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3748:17: Candidate function not viable: no known conversion from 'typename boost::detail::sp_if_not_array<PointCloud<PointXYZI> >::type' (aka 'shared_ptr<pcl::PointCloud<pcl::PointXYZI> >') to 'std::__1::shared_ptr<pcl::PointCloud<pcl::PointXYZI> >' for 1st argument
...you are using a newer version of PCL in which boost::shared_ptr has been replaced by std::shared_ptr:
#include <pcl/common/projection_matrix.h>
#include <pcl/point_types.h>
//#include <boost/make_shared.hpp> // boost::make_shared
#include <memory> // std::make_shared
typedef pcl::PointCloud<pcl::PointXYZI> PointCloudType;
int main() {
std::vector<PointCloudType::Ptr> clusterPtr(2);
for(int i = 0; i < clusterPtr.size(); ++i) {
clusterPtr[i] = std::make_shared<PointCloudType>(); // std::make_shared
}
}
I would expect that std::reference_wrapper would work as a reference in terms of converting non-const into const, like:
int a = 10;
int& refA = a;
const int& constRefA = refA;
The following code compiles and works fine in MSVC and GCC, but not on Clang. I just don't understand why, is it UB, or actually an issue on Clang compiler?
#include <functional>
#include <optional>
int main()
{
int a = 10;
std::reference_wrapper<int> ref = a;
std::reference_wrapper<const int> constRef = ref;
std::optional<std::reference_wrapper<int>> optRef = a;
std::optional<std::reference_wrapper<const int>> optConstRef = optRef;
return 0;
}
On Clang only, displays the following error:
prog.cc:13:39: error: no viable conversion from 'reference_wrapper<int>' to 'reference_wrapper<const int>'
std::reference_wrapper<const int> constRef = ref;
https://wandbox.org/permlink/FSY4tCvE9B17hbVn
prog.cc:13:39: error: no viable conversion from 'reference_wrapper<int>' to 'reference_wrapper<const int>'
std::reference_wrapper<const int> constRef = ref;
^ ~~~
/opt/wandbox/clang-head/include/c++/v1/__functional_base:374:28: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::reference_wrapper<int>' to 'const std::reference_wrapper<const int> &' for 1st argument
class _LIBCPP_TEMPLATE_VIS reference_wrapper
^
/opt/wandbox/clang-head/include/c++/v1/__functional_base:374:28: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'std::reference_wrapper<int>' to 'std::reference_wrapper<const int> &&' for 1st argument
/opt/wandbox/clang-head/include/c++/v1/__functional_base:386:5: note: candidate constructor not viable: no known conversion from 'std::reference_wrapper<int>' to 'std::reference_wrapper<const int>::type &' (aka 'const int &') for 1st argument
reference_wrapper(type& __f) _NOEXCEPT
^
/opt/wandbox/clang-head/include/c++/v1/__functional_base:389:14: note: candidate constructor not viable: no known conversion from 'std::reference_wrapper<int>' to 'std::reference_wrapper<const int>::type &&' (aka 'const int &&') for 1st argument
private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
^
/opt/wandbox/clang-head/include/c++/v1/__functional_base:394:5: note: candidate function
operator type&() const _NOEXCEPT {return *__f_;}
^
prog.cc:16:54: error: no viable conversion from 'optional<reference_wrapper<int>>' to 'optional<reference_wrapper<const int>>'
std::optional<std::reference_wrapper<const int>> optConstRef = optRef;
^ ~~~~~~
/opt/wandbox/clang-head/include/c++/v1/optional:689:41: note: candidate constructor not viable: no known conversion from 'std::optional<std::reference_wrapper<int>>' to 'const std::optional<std::reference_wrapper<const int>> &' for 1st argument
_LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
^
/opt/wandbox/clang-head/include/c++/v1/optional:690:41: note: candidate constructor not viable: no known conversion from 'std::optional<std::reference_wrapper<int>>' to 'std::optional<std::reference_wrapper<const int>> &&' for 1st argument
_LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
^
/opt/wandbox/clang-head/include/c++/v1/optional:691:41: note: candidate constructor not viable: no known conversion from 'std::optional<std::reference_wrapper<int>>' to 'std::nullopt_t' for 1st argument
_LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
^
/opt/wandbox/clang-head/include/c++/v1/optional:715:15: note: candidate template ignored: substitution failure [with _Up = std::optional<std::reference_wrapper<int>> &]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
constexpr optional(_Up&& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:730:5: note: candidate template ignored: substitution failure [with _Up = std::reference_wrapper<int>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
optional(const optional<_Up>& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:748:5: note: candidate template ignored: substitution failure [with _Up = std::reference_wrapper<int>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
optional(optional<_Up>&& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:701:24: note: explicit constructor is not a candidate
constexpr explicit optional(_InPlaceT, _Args&&... __args)
^
/opt/wandbox/clang-head/include/c++/v1/optional:722:24: note: explicit constructor is not a candidate
constexpr explicit optional(_Up&& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:738:14: note: explicit constructor is not a candidate
explicit optional(const optional<_Up>& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:756:14: note: explicit constructor is not a candidate
explicit optional(optional<_Up>&& __v)
^
2 errors generated.
The std library you are using on wandbox has a bug. It only found 2 constructors and a conversion operator.
Compilers and standard libraries are not always in sync.
printf("Hello World");
int a = 10;
std::reference_wrapper<int> ref = a;
std::reference_wrapper<const int> constRef( ref );
std::optional<std::reference_wrapper<int>> optRef = a;
std::optional<std::reference_wrapper<const int>> optConstRef( optRef );
return 0;
By making the conversions explicit it works. I don't know why; there aren't any explicit conversions differences in my reading of reference_wrapper construction and conversion operators.
But the lack of implicit reference wrapping conversion would explain why the optional would want it.
In any case, this is clearly a bug. The universal conversion constructor for reference_wrapper<const int> should apply if:
void FUN(int const&) {}
FUN(ref)
overload resolution works, and it does for a reference_wrapper<int>.
The following code compiles with g++ -std=c++11 but not with clang++ -std=c++11.
Questions
What is the meaning of the single colon "operator" in this context?
Clarification/Edit: How does GCC interpret the code?
How can I make GCC not compile this code? (Assuming that Clang follows the C++ Standard here.) Is there a flag for this?
Code
Compile with g++ -std=c++11 main.cpp and clang++ -std=c++11 main.cpp. I am using GCC 4.8 and Clang 6.0.0 (trunk).
#include <iostream>
#include <vector>
enum Dir { LEFT, RIGHT };
int main(int argc, char** argv) {
// Interesting line: Notice the single ':'
std::vector<Dir> dirs = { Dir:LEFT, Dir:RIGHT };
for (auto v: dirs) {
std::cout << v << std::endl;
}
return 0;
}
Clang Error Message
For completeness and search-ability:
$ clang++ -std=c++11 main.cpp
main.cpp:7:29: warning: use of GNU old-style field designator extension [-Wgnu-designator]
std::vector<Dir> dirs = { Dir:LEFT, Dir:RIGHT };
^~~~
.Dir =
main.cpp:7:39: warning: use of GNU old-style field designator extension [-Wgnu-designator]
std::vector<Dir> dirs = { Dir:LEFT, Dir:RIGHT };
^~~~
.Dir =
main.cpp:7:20: error: no matching constructor for initialization of 'std::vector<Dir>'
std::vector<Dir> dirs = { Dir:LEFT, Dir:RIGHT };
^ ~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:269:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'std::vector::size_type' (aka 'unsigned long') for 1st argument
vector(size_type __n, const allocator_type& __a = allocator_type())
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:281:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'std::vector::size_type' (aka 'unsigned long') for 1st argument
vector(size_type __n, const value_type& __value,
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:331:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'const std::vector<Dir, std::allocator<Dir> >' for 1st argument
vector(const vector& __x, const allocator_type& __a)
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:340:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'std::vector<Dir, std::allocator<Dir> >' for 1st argument
vector(vector&& __rv, const allocator_type& __m)
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:364:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'initializer_list<std::vector<Dir, std::allocator<Dir> >::value_type>'
(aka 'initializer_list<Dir>') for 1st argument
vector(initializer_list<value_type> __l,
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:392:9: note: candidate template ignored: substitution failure [with _InputIterator = void]: no type named 'iterator_category' in 'std::iterator_traits<void>'
vector(_InputIterator __first, _InputIterator __last,
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:256:7: note: candidate constructor not viable: requires single argument '__a', but 2 arguments were provided
vector(const allocator_type& __a)
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:310:7: note: candidate constructor not viable: requires single argument '__x', but 2 arguments were provided
vector(const vector& __x)
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:327:7: note: candidate constructor not viable: requires single argument '__x', but 2 arguments were provided
vector(vector&& __x) noexcept
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:248:7: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
vector()
^
2 warnings and 1 error generated.
To cause gcc to reject the code, use -pedantic switch.
The colon is an extension in GNU mode: X:Y means .X = Y, which is a designated initializer. (Neither of these are supported in ISO C++).
gcc also accepts the following code:
std::vector<int> v = { .a = 1, .b = 2 };
but rejects the code:
struct S { int p, q; S() {} };
S s = { .a = 1, .b = 2 }; // S has no member named 'a'
I guess this is a compiler bug; something about initializing a std::vector<int> causes it to ignore the names of the designated initializers. Note, this sort of thing is a hallmark of non-standard features: often the very reason they aren't in the standard is that they didn't mix well with other language features and nobody could come up with a sensible proposal to handle all possible cases.
Here is the MCVE:
#include <iostream>
#include <regex>
std::string s()
{
return "test";
}
int main()
{
static const std::regex regex(R"(\w)");
std::smatch smatch;
if (std::regex_search(s(), smatch, regex)) {
std::cout << smatch[0] << std::endl;
}
return 0;
}
It compiles fine with:
$ clang++ -std=c++11 main.cpp
but not with:
$ clang++ -std=c++14 main.cpp
Error message in the later case (with -std=c++14):
main.cpp:14:9: error: call to deleted function 'regex_search'
if (std::regex_search(s(), smatch, regex)) {
^~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:5998:1: note:
candidate function [with _ST = std::__1::char_traits<char>, _SA = std::__1::allocator<char>,
_Ap = std::__1::allocator<std::__1::sub_match<std::__1::__wrap_iter<const char *> > >, _Cp =
char, _Tp = std::__1::regex_traits<char>] has been explicitly deleted
regex_search(const basic_string<_Cp, _ST, _SA>&& __s,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2876:5: note:
candidate function [with _ST = std::__1::char_traits<char>, _SA = std::__1::allocator<char>,
_Ap = std::__1::allocator<std::__1::sub_match<std::__1::__wrap_iter<const char *> > >, _Cp =
char, _Tp = std::__1::regex_traits<char>]
regex_search(const basic_string<_Cp, _ST, _SA>& __s,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2851:5: note:
candidate template ignored: deduced conflicting types for parameter '_Bp'
('std::__1::basic_string<char>' vs. 'std::__1::match_results<std::__1::__wrap_iter<const char
*>, std::__1::allocator<std::__1::sub_match<std::__1::__wrap_iter<const char *> > > >')
regex_search(_Bp, _Bp, const basic_regex<_Cp, _Tp>&,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2857:5: note:
candidate template ignored: could not match 'const _Cp *' against 'std::string' (aka
'basic_string<char, char_traits<char>, allocator<char> >')
regex_search(const _Cp*, const _Cp*,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2863:5: note:
candidate template ignored: could not match 'const _Cp *' against 'std::string' (aka
'basic_string<char, char_traits<char>, allocator<char> >')
regex_search(const _Cp*, match_results<const _Cp*, _Ap>&, const basic_regex<_Cp, _Tp>&,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2869:5: note:
candidate template ignored: could not match 'basic_regex' against 'match_results'
regex_search(const basic_string<_Cp, _ST, _SA>& __s,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:5963:1: note:
candidate template ignored: could not match 'const _CharT *' against 'std::string' (aka
'basic_string<char, char_traits<char>, allocator<char> >')
regex_search(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2839:5: note:
candidate function template not viable: requires at least 4 arguments, but 3 were provided
regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2845:5: note:
candidate function template not viable: requires at least 4 arguments, but 3 were provided
regex_search(const _Cp*, const _Cp*, match_results<const _Cp*, _Ap>&,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/regex:2884:5: note:
candidate function template not viable: requires at least 4 arguments, but 3 were provided
regex_search(__wrap_iter<_Iter> __first,
^
1 error generated.
Compiler version information:
$ clang++ -v
Apple LLVM version 7.0.0 (clang-700.0.72)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
So, what's wrong?
There was a change going from C++11 to C++14 where std::regex_search is no longer allowed to take a r-value
template< class STraits, class SAlloc,
class Alloc, class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>&&,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc>&,
const std::basic_regex<CharT, Traits>&,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default ) = delete;
This was added as the overload that takes a const std::string&
is prohibited from accepting temporary strings, otherwise this function populates match_results m with string iterators that become invalid immediately.
So you can no longer pass a temporary to std::regex_search as of C++14
To fix your code we would simply store the return from s() into a variable in main and use that to call std::regex_search.
#include <iostream>
#include <regex>
std::string s()
{
return "test";
}
int main()
{
static const std::regex regex(R"(\w)");
std::smatch smatch;
auto search = s();
if (std::regex_search(search, smatch, regex)) {
std::cout << smatch[0] << std::endl;
}
return 0;
}
Live Example
This changed between C++11 and C++14. If we go to the cppreference section for std::regex_search we can see that overload that takes an rvalue reference was deleted since C++14:
template< class STraits, class SAlloc,
class Alloc, class CharT, class Traits > bool regex_search( const std::basic_string<CharT,STraits,SAlloc>&&,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc
>&,
const std::basic_regex<CharT, Traits>&,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default ) = delete;
It was changed due to LWG issue 2329: regex_match()/regex_search() with match_results should forbid temporary strings which says (emphasis mine):
Consider the following code:
const regex r(R"(meow(\d+)\.txt)");
smatch m;
if (regex_match(dir_iter->path().filename().string(), m, r)) {
DoSomethingWith(m[1]);
}
This occasionally crashes. The problem is that
dir_iter->path().filename().string() returns a temporary string, so
the match_results contains invalidated iterators into a destroyed
temporary string.
It's fine for regex_match/regex_search(str, reg) to accept temporary
strings, because they just return bool. However, the overloads taking
match_results should forbid temporary strings.
and indeed if we use a non-temporary:
std::string s1 = s() ;
if (std::regex_search(s1, smatch, regex)) {
//...
}
it compiles (see it live) and no longer exhibits undefined behavior.
Interesting to note that gcc/libstdc++ has this overload deleted in C++11 mode as well see it live. Since this is undefined behavior it seems like a good solution.
This issue also pops up in other areas of the library see Visual Studio regex_iterator Bug? which deals with the same issue but with regex_iterator/regex_token_iterator.
This not a bug, but expected behaviour.
The reason is that s() returns a temporary string, regex_search makes use of regex_match and consequently if a temporary string was utilized match results would contain iterators to a string that no longer exists. This would have been undefined behaviour. Thus, the committee abolished this regex_search overload in C++14.
You can also confirm in the standard 28.4 Header synopsis [re.syn]:
template <class ST, class SA, class Allocator, class charT, class traits>
bool regex_search(const basic_string<charT, ST, SA>&&,
match_results<
typename basic_string<charT, ST, SA>::const_iterator,
Allocator>&,
const basic_regex<charT, traits>&,
regex_constants::match_flag_type =
regex_constants::match_default) = delete;
As you can see the overload that takes a rvalue to a basic_string is marked deleted.