std::endl and variadic template [duplicate] - c++

This question already has answers here:
Cannot have typeof(std::endl) as template parameter?
(2 answers)
Closed 9 years ago.
Code:
#include <iostream>
void out()
{
}
template<typename T, typename... Args>
void out(T value, Args... args)
{
std::cout << value;
out(args...);
}
int main()
{
out("12345", " ", 5, "\n"); // OK
out(std::endl); // compilation error
return 0;
}
Build errors:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -pthread -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
../main.cpp: In function ‘int main()’:
../main.cpp:17:15: error: no matching function for call to ‘out(<unresolved overloaded function type>)’
../main.cpp:17:15: note: candidates are:
../main.cpp:3:6: note: void out()
../main.cpp:3:6: note: candidate expects 0 arguments, 1 provided
../main.cpp:8:6: note: template<class T, class ... Args> void out(T, Args ...)
../main.cpp:8:6: note: template argument deduction/substitution failed:
../main.cpp:17:15: note: couldn't deduce template parameter ‘T’
So, everything is OK except std::endl. How can I fix this (except of using "\n")?

std::endl is an overloaded function, (in many STL implementations, a template) and the compiler has no info about what to choose from.
Just cast it as static_cast<std::ostream&(*)(std::ostream&)>(std::endl)

Related

Expand template parameter pack to non-type template argument [duplicate]

This question already has answers here:
C-Style Strings as template arguments? [duplicate]
(8 answers)
Passing a string literal as a type argument to a class template
(17 answers)
Closed 1 year ago.
I want to do something on strings in the compile-time, so I wrote a class with non-type parameters. Detail is below.
This is my code, compiled by Clang 11.0.1, C++20
#include <type_traits>
// my non-type template parameters string class
template<char... str>
struct StaticString
{
static constexpr char data[] = { str... };
};
// I will do something in this function, but now just return the character.
template<std::size_t N>
constexpr char nthChar(const char (&str)[N], std::size_t i) { return str[i]; }
// success to compile
inline constexpr char testNthChar = nthChar("xxx", 2);
template<std::size_t N, std::size_t... i>
constexpr auto makeStaticString(const char (&str)[N], std::index_sequence<i...>)
{
return StaticString<nthChar(str, i)...>{};
// ^~~~~~~~~~~~~~~
// error: non-type template argument is not a constant expression
// I tend to think that I made a mistake...
}
template<std::size_t N>
constexpr auto buildStr(const char(&str)[N])
{
// make an index sequence that is used to provide an index to get chars in str
return makeStaticString(str, std::make_index_sequence<N>{}).data;
}
extern const char sf[] = "1234";
void foo()
{
constexpr auto ss = buildStr("0123");
// not caused by internal linkage attribute
// constexpr auto ssExtern = buildStr(sf);
}
The full compiler error:
[build] D:\LLVM\bin\clang++.exe -g -Xclang -gcodeview -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -std=gnu++20 -MD -MT CMakeFiles/test.dir/test.cpp.obj -MF CMakeFiles\test.dir\test.cpp.obj.d -o CMakeFiles/test.dir/test.cpp.obj -c ../test.cpp
[build] ../test.cpp:21:22: error: non-type template argument is not a constant expression
[build] return StaticString<nthChar(str, i)...>{};
[build] ^~~~~~~~~~~~~~~
[build] ../test.cpp:27:9: note: in instantiation of function template specialization 'makeStaticString<4, 0>' requested here
[build] return makeStaticString(str, std::make_index_sequence<1>{}).data;
[build] ^
[build] ../test.cpp:33:22: note: in instantiation of function template specialization 'buildStr<4>' requested here
[build] constexpr auto ss = buildStr("123");
[build] ^
[build] ../test.cpp:21:30: note: function parameter 'str' with unknown value cannot be used in a constant expression
[build] return StaticString<nthChar(str, i)...>{};
[build] ^
[build] 1 error generated.
So my question is, possible to expand the template parameters pack to non-type template arguments, or what is the mistake I made?
I would appreciate your help!

C++ "...does not name a type"

I've been trying to define a class method which uses a return type declared in the class namespace:
template<class T, int SIZE>
class SomeList{
public:
class SomeListIterator{
//...
};
using iterator = SomeListIterator;
iterator begin() const;
};
template<class T, int SIZE>
iterator SomeList<T,SIZE>::begin() const {
//...
}
When I try to compile the code, I'm getting this error:
Building file: ../SomeList.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"SomeList.d" -MT"SomeList.d" -o "SomeList.o" "../SomeList.cpp"
../SomeList.cpp:17:1: error: ‘iterator’ does not name a type
iterator SomeList<T,SIZE>::begin() const {
^
make: *** [SomeList.o] Error 1
I Also tried to define the method like this:
template<class T, int SIZE>
SomeList::iterator SomeList<T,SIZE>::begin() const {
//...
}
And this:
template<class T, int SIZE>
SomeList<T,SIZE>::iterator SomeList<T,SIZE>::begin() const {
//...
}
Result:
Building file: ../SomeList.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"SomeList.d" -MT"SomeList.d" -o "SomeList.o" "../SomeList.cpp"
../SomeList.cpp:17:1: error: invalid use of template-name ‘SomeList’ without an argument list
SomeList::iterator SomeList<T,SIZE>::begin() const {
^
make: *** [SomeList.o] Error 1
What am I doing wrong?
The name iterator is scoped to your class and it is a dependent name. In order to use it you need to use the scope operator and the typename keyword
typename SomeList<T,SIZE>::iterator SomeList<T,SIZE>::begin() const
Live Example
As pointed out in the comment by M.M you can also use the trailing return syntax as
auto SomeList<T,SIZE>::begin() const -> iterator {
Live Example

std::basic_regex<char32_t>, Is someone already try it?

2 problem:
#include <iostream>
#include <string>
#include <regex>
int main() {
std::u32string lines[] = {U"Roses are #ff0000",
U"violets are #0000ff",
U"all of my base are belong to you"};
std::basic_regex<char32_t> color_regex(U"#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})");
/*
for (const auto &line : lines) {
std::cout << line << ": "
<< std::regex_search(line, color_regex) << '\n';
}
std::smatch color_match;
for (const auto &line : lines) {
std::regex_search(line, color_match, color_regex);
std::cout << "matches for '" << line << "'\n";
for (size_t i = 0; i < color_match.size(); ++i) {
std::ssub_match sub_match = color_match[i];
std::string sub_match_str = sub_match.str();
std::cout << i << ": " << sub_match_str << '\n';
}
}
*/
return 0;
}
compile with gcc : it work:
g++ -g -O0 -std=c++11 regexp.cpp -o executable
compile with clang: it not work at all:
clang++ -g -O0 -std=c++11 regexp.cpp -o executable
execute with gcc generated file:
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
Abandon (core dumped)
error in clang compilation:
In file included from regexp.cpp:3:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/regex:60:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:413:20: error: non-type template argument is not a constant expression
std::bitset<1 << (8 * sizeof(_CharT))>,
^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:398:53: note: in instantiation of template class 'std::__detail::_BracketMatcher<std::regex_traits<char32_t>, false, false>' requested here
_BracketMatcher<_TraitsT, __icase, __collate> __matcher
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:316:25: note: in instantiation of function template specialization 'std::__detail::_Compiler<std::regex_traits<char32_t>
>::_M_insert_character_class_matcher<false, false>' requested here
__INSERT_REGEX_MATCHER(_M_insert_character_class_matcher);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:288:8: note: expanded from macro '__INSERT_REGEX_MATCHER'
__func<false, false>(args);\
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:136:17: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_atom' requested here
if (this->_M_atom())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:118:17: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_term' requested here
if (this->_M_term())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:97:13: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_alternative' requested here
this->_M_alternative();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.tcc:82:13: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_M_disjunction' requested here
this->_M_disjunction();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:155:14: note: in instantiation of member function 'std::__detail::_Compiler<std::regex_traits<char32_t> >::_Compiler' requested here
return _Cmplr(__first, __last, __traits, __flags)._M_get_nfa();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex.h:524:27: note: in instantiation of function template specialization 'std::__detail::__compile_nfa<std::regex_traits<char32_t> >' requested here
_M_automaton(__detail::__compile_nfa(_M_original_str.c_str(),
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex.h:452:9: note: in instantiation of function template specialization 'std::basic_regex<char32_t, std::regex_traits<char32_t> >::basic_regex<const
char32_t *>' requested here
: basic_regex(__p, __p + _Rx_traits::length(__p), __f)
^
regexp.cpp:10:29: note: in instantiation of member function 'std::basic_regex<char32_t, std::regex_traits<char32_t> >::basic_regex' requested here
std::basic_regex<char32_t> color_regex(U"#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})");
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/regex_compiler.h:413:22: note: shift count 32 >= width of type 'int' (32 bits)
std::bitset<1 << (8 * sizeof(_CharT))>,
^
...
...
...
...
Have someone already try it?
$ clang --version
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix
$ g++ --version
g++ (Ubuntu 4.9.1-3ubuntu2~14.04.1) 4.9.1
According to this reference
Two specializations of std::regex_traits are defined by the standard library:
std::regex_traits<char>
std::regex_traits<wchar_t>
These specializations make it possible to use std::basic_regex<char> (aka std::regex) and std::basic_regex<wchar_t> (aka std::wregex), but in order to use, for example, std::basic_regex<char32_t>, user-provided specializtion std::regex_traits<char32_t> needs to be defined.
std::regex_traits<char32_t> is not provided by the standard. You must implement it yourself in order to use std::basic_regex<char32_t>.

Variadic template not compiled [duplicate]

This question already has answers here:
Cannot have typeof(std::endl) as template parameter?
(2 answers)
Closed 9 years ago.
Code:
#include <iostream>
template<typename T>
void out() // line 4
{
}
template<typename T, typename... Args>
void out(T value, Args... args) // line 9
{
std::cout << value;
out(args...); // line 12
}
int main()
{
out("12345", std::endl); // line 17
return 0;
}
Build errors:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -pthread -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
../main.cpp: In function ‘int main()’:
../main.cpp:17:24: error: no matching function for call to ‘out(const char [6], <unresolved overloaded function type>)’
../main.cpp:17:24: note: candidates are:
../main.cpp:4:6: note: template<class T> void out()
../main.cpp:4:6: note: template argument deduction/substitution failed:
../main.cpp:17:24: note: candidate expects 0 arguments, 2 provided
../main.cpp:9:6: note: void out(T, Args ...) [with T = const char*; Args = {}]
../main.cpp:9:6: note: candidate expects 1 argument, 2 provided
I want this program to give the same result as std::cout << "12345" << std::endl; What is wrong in the template function?
The problem is that you made your no argument version of out be a template, and it cannot be called without explicitly supplying template arguments. Thus
void out() {}
template<typename T, typename... Args>
void out(T value, Args... args) {
std::cout << value;
out(args...);
}
int main() {
out(1, 2.0, "3");
return 0;
}
works as intended.
There is a syntax error (a missning .) that makes the compiler go crazy.
After that, you may also have a problem with the out("12345", std::endl) call, being std::endl an overridden function that compiler cannot choose from (just cast it as static_cast<std::ostream&(*)(std::ostream&)>(std::endl))
Also, the recursion in out ends in a out() call, but there is no out with 0 parameters.(see also yuri answer: https://stackoverflow.com/a/20879525/924727 )

Error passing arguments to template function with const qualifier

I have this code example:
#include <iostream>
#include <memory>
template <typename T>
void func1(T& value)
{
std::cout << "passed 1 ..." << std::endl;
}
template <template <typename> class T, typename U>
void func2(T<U>& value)
{
std::cout << "passed 2 ..." << std::endl;
}
int main()
{
std::auto_ptr<int> a;
const std::auto_ptr<int> ca;
// case 1: using func1
func1(a); // OK
func1(ca); // OK
// case 2: using func2
func2(a); // OK
func2(ca); // Compilation error
return 0;
}
In the first case the function 'func1' accepts a generic argument regardless of the qualifier, however the second case the function 'func2' fails when the argument has the const qualifier. Why this happens ?
This is the compilation error:
make all
Building file: ../src/Test2.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Test2.d" -MT"src/Test2.d" -o "src/Test2.o" "../src/Test2.cpp"
../src/Test2.cpp: In function ‘int main()’:
../src/Test2.cpp:27: error: invalid initialization of reference of type ‘std::auto_ptr<int>&’ from expression of type ‘const std::auto_ptr<int>’
../src/Test2.cpp:11: error: in passing argument 1 of ‘void func2(T<U>&) [with T = std::auto_ptr, U = int]’
make: *** [src/Test2.o] Error 1
The problem is that in the case of func1, the compiler needs to deduce T and we get
T is std::auto_ptr<int> in the first call
T is const std::auto_ptr<int> in the second call
In both cases T is valid in itself.
Now for func2, the compiler needs to deduce T and U, where T is a template template parameter. What would be needed is:
T is std::auto_ptr, U is int in the first call
T is const std::auto_ptr, U is int in the second call
and there's your problem: T can not be const std::auto_ptr itself, as it combined a type-property const with a template std::auto_ptr which is not a valid type.