I'm new to C++ and I read that "using namespace std;" is considered bad practice. I used the following code to test if my compiler was c++14 compliant:
#include <iostream>
#include <string>
using namespace std;
auto add([](auto a, auto b){ return a+b ;});
auto main() -> int {cout << add("We have C","++14!"s);}
No errors. Then I started to play around with the code – as you do... when you learn something new. So I commented out using namespace std; and replaced cout with std::cout. Now the code looked like this:
#include <iostream>
#include <string>
//using namespace std;
auto add([](auto a, auto b){ return a+b ;});
auto main() -> int {std::cout << add("We have C","++14!"s);}
Build Messages:
||=== Build: Release in c++14-64 (compiler: GNU GCC Compiler) ===|
C:\CBProjects\c++14-64\c++14-64-test.cpp||In function 'int main()':|
C:\CBProjects\c++14-64\c++14-64-test.cpp|5|error: unable to find string literal operator 'operator""s' with 'const char [6]', 'long long unsigned int' arguments|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Questions:
What causes the error in the second program?
How to avoid using namespace std in this case?
clang++ gives a good error message:
error: no matching literal operator for call to 'operator""s' with arguments of types 'const char *' and 'unsigned long', and no matching literal operator template
auto main() -> int { std::cout << add("We have C", "++14!"s); }
^
You use string literals and more precisely operator""s.
By removing using namespace std; you have to specify the namespace where the operator is defined.
With an explicit call:
int main() {
std::cout << add("We have C", std::operator""s("++14!", 5));
// Note the length of the raw character array literal is required
}
or with a using declaration:
int main() {
using std::operator""s;
std::cout << add("We have C", "++14!"s);
}
Related
I use this code with std=c++14 and gcc7.3:
#include <iostream>
#include <string>
#include <type_traits>
#include <boost/hana/assert.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/type.hpp>
namespace hana = boost::hana;
template<class T>
bool foo(T elem)
{
constexpr auto has_overload_to_string = hana::is_valid([](auto t) -> decltype(to_string(t)) {});
constexpr bool hasOverloadTo_string = has_overload_to_string(elem);
return hasOverloadTo_string;
}
int main()
{
std::string elem;
std::cin >> elem;
foo(elem);
}
And it works fine : demo
If now I use gcc10.1, I got this error: demo fail
prog.cc: In instantiation of 'bool foo(T) [with T = std::__cxx11::basic_string<char>]':
prog.cc:41:13: required from here
prog.cc:27:38: error: temporary of non-literal type 'foo<std::__cxx11::basic_string<char> >::<lambda(auto:1)>' in a constant expression
27 | [[maybe_unused]] constexpr auto has_overload_to_string =
| ^~~~~~~~~~~~~~~~~~~~~~
prog.cc:28:21: note: 'foo<std::__cxx11::basic_string<char> >::<lambda(auto:1)>' is not literal because:
28 | hana::is_valid([](auto t) -> decltype(to_string(t)) {});
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: note: 'foo<std::__cxx11::basic_string<char> >::<lambda(auto:1)>' is a closure type, which is only literal in C++17 and later
My question is : Is gcc7.3 too permissive with C++14 and is_valid works when it shouldn't or gcc8 and more add a bug with C++14 ?
The error has nothing to do with hana::is_valid, but the lambda is not valid in a constant expression in C++14.
There is already a good language lawyer answer for this here:
https://stackoverflow.com/a/32697323/800347
Clang also consistently provides an error, so it's clear that previous versions of gcc were incorrect in allowing this.
To workaround this, simply remove the constexpr qualifier to your variable declaration.
Going by the opening paragraph of the boost::spirit::qi::symbols documentation, I assumed that it wouldn't be too hard to add symbols to a qi::symbols from a semantic action. Unfortunately it appears to be not as straightforward as I would have assumed.
The following bit of test code exhibits the problem:
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
namespace qi = boost::spirit::qi;
typedef qi::symbols<char, unsigned int> constants_dictionary;
template <typename Iter> struct parser : public qi::grammar<Iter, qi::space_type> {
parser(constants_dictionary &dict) : parser::base_type(start) {
start = qi::lit("#") >> ((+qi::char_) >> qi::uint_)[dict.add(qi::_1, qi::_2)];
}
qi::rule<Iter> start;
};
int main() {
constants_dictionary dict;
parser<std::string::const_iterator> prsr(dict);
std::string test = "#foo 3";
parse(test.begin(), test.end(), prsr, qi::space);
}
Gives type errors related to qi::_2 from VS2010:
C:\Users\k\Coding\dashCompiler\spirit_test.cpp(12) : error C2664: 'const boost::
spirit::qi::symbols<Char,T>::adder &boost::spirit::qi::symbols<Char,T>::adder::o
perator ()<boost::spirit::_1_type>(const Str &,const T &) const' : cannot conver
t parameter 2 from 'const boost::spirit::_2_type' to 'const unsigned int &'
with
[
Char=char,
T=unsigned int,
Str=boost::spirit::_1_type
]
Reason: cannot convert from 'const boost::spirit::_2_type' to 'const uns
igned int'
No user-defined-conversion operator available that can perform this conv
ersion, or the operator cannot be called
C:\Users\k\Coding\dashCompiler\spirit_test.cpp(10) : while compiling cla
ss template member function 'parser<Iter>::parser(constants_dictionary &)'
with
[
Iter=std::_String_const_iterator<char,std::char_traits<char>,std::al
locator<char>>
]
C:\Users\k\Coding\dashCompiler\spirit_test.cpp(21) : see reference to cl
ass template instantiation 'parser<Iter>' being compiled
with
[
Iter=std::_String_const_iterator<char,std::char_traits<char>,std::al
locator<char>>
]
(Apologies for the nasty VS2010 error-style)
What syntax am I supposed to be using to add (and later on, remove) symbols from this table?
This question has been answered before. However, there is quite a range of problems with your posted code, so I'll fix them up one by one to spare you unnecessary staring at pages of error messages.
The working code (plus verification of output) is here on liveworkspace.org.
Notes:
the semantic action must be a Phoenix actor, i.e. you need
boost::bind, phoenix::bind, std::bind
phoenix::lambda<> or phoenix::function<>
a function pointer or polymorphic calleable object (as per the documentation)
I'd recommend phoenix::bind (in this particular case), which I show below
There was a mismatch between the parser's skipper and the start rule
qi::char_ eats all characters. Combined with the skipper, this resulted
in parse failure, because (obviously) the digits in the value were also being
eaten by +qi::char_. I show you one of many solutions, based on qi::lexeme[+qi::graph]
use qi::lexeme to 'bypass' the skipper (i.e. to prevent +qi::graph to cut
across whitespace because the skipper, well, skipped it)
qi::parse doesn't take a skipper; use qi::phrase_parse for that (the
reason it appeared to work is that any trailing 'variadic' arguments are
bound to the exposed attributes of the parser, which in this case are
unspecified, and therefore qi::unused_type).
if you want to pass test.begin() and test.end() directly to
qi::phrase_parse, you need to make it clear that you want const iterators. The
more typical solution would be to introduce explicitely typed variables
(first and last, e.g.)
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef qi::symbols<char, unsigned int> constants_dictionary;
template <typename Iter> struct parser : qi::grammar<Iter, qi::space_type>
{
parser(constants_dictionary &dict) : parser::base_type(start)
{
start = qi::lit("#") >> (qi::lexeme [+qi::graph] >> qi::uint_)
[ phx::bind(dict.add, qi::_1, qi::_2) ]
;
}
qi::rule<Iter, qi::space_type> start;
};
int main() {
constants_dictionary dict;
parser<std::string::const_iterator> prsr(dict);
const std::string test = "#foo 3";
if (qi::phrase_parse(test.begin(), test.end(), prsr, qi::space))
{
std::cout << "check: " << dict.at("foo") << "\n";
}
}
I'm trying to use thrust::transform to operate on vectors of type thrust:complex<float> without success. The following example blows up during compilation with several pages of errors.
#include <cuda.h>
#include <cuda_runtime.h>
#include <cufft.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/transform.h>
#include <thrust/complex.h>
int main(int argc, char *argv[]) {
thrust::device_vector< thrust::complex<float> > d_vec1(4);
thrust::device_vector<float> d_vec2(4);
thrust::fill(d_vec1.begin(), d_vec1.end(), thrust::complex<float>(1,1));
thrust::transform(d_vec1.begin(), d_vec1.end(), d_vec2.begin(), thrust::abs< thrust::complex<float> >() );
}
I'm using CUDA 8.0 on Ubuntu Xenial and compiling with clang 3.8.0-2ubuntu4 using nvcc --std=c++11 main.cpp -o main.
Main errors appear to be:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:17:105: error: no matching function for call to ‘abs()’
gin(), d_vec1.end(), d_vec2.begin(), thrust::abs< thrust::complex<float> >() );
and
/usr/local/cuda-8.0/bin/../targets/x86_64-linux/include/thrust/detail/complex/arithmetic.h:143:20: note: template argument deduction/substitution failed:
main.cpp:17:105: note: candidate expects 1 argument, 0 provided
gin(), d_vec1.end(), d_vec2.begin(), thrust::abs< thrust::complex<float> >() );
^
No problem working on real floats, but no such with complex ones. I'm thinking there's a type error that I'm missing, but I'm very much still on the steep part of the learning curve with Thrust & templates.
The error message is quite descriptive:
thrust::abs<thrust::complex<...>> is a function which expects exactly one parameter, see thrust/detail/complex/arithmetic.h#L143:
template <typename ValueType>
__host__ __device__
inline ValueType abs(const complex<ValueType>& z){
return hypot(z.real(),z.imag());
}
For your use case, you need to wrap that function by a functor:
struct complex_abs_functor
{
template <typename ValueType>
__host__ __device__
ValueType operator()(const thrust::complex<ValueType>& z)
{
return thrust::abs(z);
}
};
Finally, employ that functor here:
thrust::transform(d_vec1.begin(),
d_vec1.end(),
d_vec2.begin(),
complex_abs_functor());
I have this test source:
#include <stdio.h>
int main()
{
int x;
printf("x=%d\n", _Generic('x', int: 1, default: 0));
return 0;
}
Compiling with c++ (from GCC 4.9.2) fails:
t.cpp: In function ‘int main()’:
t.cpp:7:33: error: expected primary-expression before ‘int’
printf("x=%d\n", _Generic('x', int: 1, default: 0));
^
t.cpp:7:41: error: expected primary-expression before ‘default’
printf("x=%d\n", _Generic('x', int: 1, default: 0));
^
t.cpp:7:51: error: ‘_Generic’ was not declared in this scope
printf("x=%d\n", _Generic('x', int: 1, default: 0));
The compiler arguments are:
c++ --std=c++11 t.cpp -o t
What am I doing wrong?
_Generic is a C11 feature. It is not present in C++ (any version at least up to C++14 - I don't really expect it to be added either).
If you want to use it, you'll need to write C code, and use a compiler that supports that standard (reasonably recent versions of gcc and clang do for example, using -std=c11).
If you want to write C++, use overloading or templates instead, for example:
#include <iostream>
int foo(int) { return 1; }
int foo(char) { return 0; }
int main()
{
std::cout << "x=" << foo('x') << std::endl;
}
This prints x=0 in C++, the foo(char) overload is the best match.
Note that there's difference between C and C++ that might trick you here too: 'x' is a char in C++. It's an int in C. So if _Generic had been implemented (maybe as an extension) by your compiler, chances are you'd get different output when compiling your example as C versus compiling as C++.
Here's the C++ form (forgive me for using the using directive, I know its bad form):
#include <iostream>
using namespace std;
template< typename T> T do_something(T argument) {
// Put here what you need
}
int main()
{
int x;
cout << "x" << (x = do_something(x));
return 0;
}
_Generic is C11, you're probably using a C++ compiler when you meant to use a C compiler.
I'm having trouble with std::initializer_list. I reduced it down to a simple example:
#include <initializer_list>
#include <cstdio>
class Test {
public:
template <typename type> Test(const std::initializer_list<type>& args) {}
};
int main(int argc, char* argv[]) {
Test({1,2});
getchar();
return 0;
}
When compiled using g++ test_initializer.cpp -std=c++0x, it compiles and runs well. However, if line 11 is changed to Test({1,2.0});, one gets:
ian#<host>:~/Desktop$ g++ test_initializer.cpp -std=c++0x
test_initializer.cpp: In function ‘int main(int, char**)’:
test_initializer.cpp:11:14: error: no matching function for call to ‘Test::Test(<brace-enclosed initializer list>)’
test_initializer.cpp:11:14: note: candidates are:
test_initializer.cpp:7:28: note: template<class type> Test::Test(const std::initializer_list<_Tp>&)
test_initializer.cpp:5:7: note: constexpr Test::Test(const Test&)
test_initializer.cpp:5:7: note: no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘const Test&’
test_initializer.cpp:5:7: note: constexpr Test::Test(Test&&)
test_initializer.cpp:5:7: note: no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘Test&&’
I suspect this happens because the compiler can't figure out what type to make the initializer list. Is there a way to fix the example so that it works with different types (and still uses initializer lists)?
An std::initializer_list takes only one type. If you need different types, you can use variadic templates:
template<typename... Args>
Test(Args&&... args);
/* ... */
int main()
{
Test(1, 2.0);
}
Would a std::tuple<int.double> work for the OP? If the code will always have a int followed by a double, then the OP could get strict type-checking for all arguments, which the variable arguments solution does not allow. The std::tuple<>, however, would not work for any number or order of values, so may not be appropriate for all use cases.
Let the initializer_list hold the most arbitrary pointers, void*, and do your own casting from there. Here is an example.
#include <initializer_list>
#include <iostream>
using std::initializer_list;
using std::cout;
using std::endl;
class Person {
private:
string _name;
int _age;
public:
Person(initializer_list<void*> init_list) {
auto it = init_list.begin();
_name = *((string*)(*it));
it++;
_age = *((int*)(*it));
}
void print() {
cout << "name: " << _name << ". age: " << _age << endl;
}
};
int main(void) {
string name{"Vanderbutenburg};
int age{23};
Person p{&name,&age};
p.print(); // "name: Vanderbutenburg. age: 23"
return 0;
}