I encountered this code
#define pii pair<int, int>
#define pip pair<int, pii>
...
vector< pip > graph;
graph[i] = pip( c, pii(u,v));
When I try
graph[i] = pair<c,pair<u,v>>;
I get an error message
error: 'c' cannot appear in a constant-expression
error: 'i' cannot appear in a constant-expression
error: 'j' cannot appear in a constant-expression
Why are these two expressions not equal?
pair is a type, not a function.
Aside from the syntax being incorrect, the reason you're getting this error is because you are trying to pass c (a run-time variable) into the template parameters, here:
graph[i] = pair<c,pair<u,v>>;
Presumably you want something like this instead:
graph[i] = pip(c, pii(u,v));
Which equates to:
graph[i] = pair<int, pair<int, int>>(c, pair<int, int>(u,v));
Related
When my static assertion triggers, I get the following error message:
In file included from test2.cpp:1:
test.h: In instantiation of ‘test::test<T, test_from,test_to>::test() [with T = Eigen::Transform<double, 3, 1>; unsigned int test_from = 3740358174u; unsigned int test_to = 837757431u]’:
test2.cpp:51:27: required from here
test.h:38:9: error: static assertion failed: Wrong number assignment. Numbers in computation are assigned to a different object.
static_assert(test_from==test_from2,"Wrong number assignment. Numbers in computation are assigned to a different object.");
^
I would like gcc to print the line and highlight the character for the "required from here" disgnostic:
In file included from test2.cpp:1:
test.h: In instantiation of ‘test::test::test() [with T = Eigen::Transform; unsigned int test_from = 3740358174u; unsigned int test_to = 837757431u]’:
test2.cpp:51:27: required from here
destination = source.inverse();
^
test.h:38:9: error: static assertion failed: Wrong number assignment. Numbers in computation are assigned to a different object.
static_assert(test_from==test_from2,"Wrong number assignment. Numbers in computation are assigned to a different object.");
^
Is there any compiler flag or code pragma I can activate to have this behaviour?
Why does the following not compile?
std::vector<int> v{1,2};
decltype(v[0]) i; //doesn't work
decltype(v)::value_type j; //works
I receive the error test.cpp:31:18: error: declaration of reference variable 'i' requires an initializer. Isn't v[0] of type int here?
I understand that even if it did work, it wouldn't be as safe as the latter in case the vector is empty, but I feel that should be a runtime issue rather than a compile time issue.
decltype(v[0]) yields you the type of expression v[0] which is a reference to the element (unless v is vector<bool>). A reference variable must be initialized, and that is what the compiler error message says.
You can use auto to get an element by value and auto& to get it by reference:
auto element = v[0];
auto& element_ref = v[0];
The following code doesn't compile, but I don't found the error (I don't unsderstand the message error).
My basic template type, 'int_mod_N', is an integer from 0 to 'N', an integer module 'N' (to represent elements of a cyclic group). This is very easy and I have constructed a library of integers represented in radix 'B', where the digits are of 'int_mod_N', and the integer is represented as 'std::basic_strings< int_mod_N >'. It works.
The problematic thing is the type I need to represent elements of a cartesian product of 'n' sets, for each of them integers module a const integer 'N_i'.
Mathematically, I want to represent elements of Z_Nn x ... x Z_N1, only the additive group.
The next code don't compile.
#include <tuple>
#include "int_mod_N_t.hpp"
template<
unsigned N_n,unsigned ... N_nm1
>
struct elem_set_t :
public
decltype(
std::tuple_cat(
std::tuple< int_mod_N_t<N_n> >{},
elem_set_t< N_nm1 ... >{}
)
)
{};
template<unsigned N_n,unsigned N_nm1>
struct elem_set_t<N_n,N_nm1> :
public
std::tuple<
int_mod_N_t<N_n> ,
int_mod_N_t<N_nm1>
>
{};
template<unsigned N_n>
struct elem_set_t<N_n> :
public
std::tuple<
int_mod_N_t<N_n>
>
{};
The error message of compiler (g++ 7.2.0), is
In file included from /tuplas_y_tipos/main.cpp:3:0:
/tuplas_y_tipos/elem_set_t.hpp: In instantiation of 'struct
elem_set_t<2, 2, 2>': /tuplas_y_tipos/main.cpp:8:20: required from
here /tuplas_y_tipos/elem_set_t.hpp:10:21: error: no matching function
for call to 'tuple_cat(std::tuple >, elem_set_t<2, 2>)'
std::tuple_cat(
~~~~~~~~~~~~~~^
std::tuple< int_mod_N_t >{},
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
elem_set_t< N_nm1 ... >{}
~~~~~~~~~~~~~~~~~~~~~~~~~
)
~ In file included from /tuplas_y_tipos/elem_set_t.hpp:1:0,
from /tuplas_y_tipos/main.cpp:3: c:\mingw\include\c++\7.2.0\tuple:1575:5: note: candidate:
template constexpr typename
std::__tuple_cat_result<_Tpls ...>::__type std::tuple_cat(_Tpls&& ...)
tuple_cat(_Tpls&&... __tpls)
^~~~~~~~~ c:\mingw\include\c++\7.2.0\tuple:1575:5: note: template argument deduction/substitution failed:
c:\mingw\include\c++\7.2.0\tuple:1572:31: error: no type named 'type'
in 'struct std::enable_if' template
elem_set_t<2,2,2> elem;
^~~~ make.exe[1]: * [tuplas_y_tipos.mk:97: Debug/main.cpp.o] Error 1 make.exe: * [Makefile:5: All] Error 2
make.exe[1]: Leaving directory '/tuplas_y_tipos'
====1 errors, 6 warnings====
I don't recommend inheriting from std::tuple at all, and for this, you don't need to.
template <unsigned ... N_ns>
using elem_set_t = std::tuple<int_mod_N_t<N_ns>...>;
If you have some methods in mind, you should have a tuple data member, not base class
template <unsigned ... N_ns>
struct elem_set_t
{
std::tuple<int_mod_N_t<N_ns>...> data;
// other members
}
I'm trying to create sub containers of a container through container<\T>(InputIt First, InputIt Last). For example, I have a string s1="AreYouOK".
The expected outputs are
A
Ar
Are
AreY
AreYo
AreYou
AreYouO
Here is my code:
#include <vector>
#include <string>
#include <iostream>
using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;
int main()
{
string s1 = "AreYouOK";
vector<string> v;
for (string::const_iterator iter = s1.begin();
iter != s1.end()-1; ++iter)
{
string s(s1.begin(),iter); // no matching container
s += *iter;
v.push_back(s);
}
for (vector<string>::const_iterator iter = v.begin();
iter != v.end(); ++iter)
{
cout << *iter <<endl;
}
return 0;
}
I expect the commented line
string s(s1.begin(),iter);
to create a substring s of string s1 in range [s1.begin(), iter), since iter is an iterator of s1. However, I was told that there is no matching constructor for initialization.
error: no matching constructor for initialization of 'string'
(aka 'basic_string<char, char_traits<char>, allocator<char> >')
string s(s1.begin(),iter);
^ ~~~~~~~~~~~~~~~
While
string s(s1.begin(),s1.begin+3);
did manage to create a substring.
Why
string s(s1.begin(),iter);
did not work?
Many thanks!
If you look here, for example, you can see that a full error message contains
prog.cpp:19:33: error: no matching function for call to 'std::basic_string<char>::basic_string(std::basic_string<char>::iterator, std::basic_string<char>::const_iterator&)'
which says that it thinks your calling a constructor that takes an iterator and (reference to) const_iterator. There is no such constructor. Since s1 is a non-const object, s1.begin() returns a regular iterator.
There are many ways around this. One of them is to change your loop to
string::const_iterator b = s1.begin();
for (string::const_iterator iter = b;
iter != s1.end()-1; ++iter)
{
string s(b,iter);
...
Here you indeed use two const iterators (see here your expected output).
Edit
Two excellent (and superior) alternatives are:
Use cbegin if you're C++11 enabled (#rici)
Use accumulate, once you get to that algorithm (#PaulMcKenzie)
Here's a short example that reproduces this “no viable conversion” with lemon for clang but valid for g++ difference in compiler behavior.
#include <iostream>
struct A {
int i;
};
#ifndef UNSCREW_CLANG
using cast_type = const A;
#else
using cast_type = A;
#endif
struct B {
operator cast_type () const {
return A{i};
}
int i;
};
int main () {
A a{0};
B b{1};
#ifndef CLANG_WORKAROUND
a = b;
#else
a = b.operator cast_type ();
#endif
std::cout << a.i << std::endl;
return EXIT_SUCCESS;
}
live at godbolt's
g++ (4.9, 5.2) compiles that silently; whereas clang++ (3.5, 3.7) compiles it
if
using cast_type = A;
or
using cast_type = const A;
// [...]
a = b.operator cast_type ();
are used,
but not with the defaulted
using cast_type = const A;
// [...]
a = b;
In that case clang++ (3.5) blames a = b:
testling.c++:25:9: error: no viable conversion from 'B' to 'A'
a = b;
^
testling.c++:3:8: note: candidate constructor (the implicit copy constructor)
not viable:
no known conversion from 'B' to 'const A &' for 1st argument
struct A {
^
testling.c++:3:8: note: candidate constructor (the implicit move constructor)
not viable:
no known conversion from 'B' to 'A &&' for 1st argument
struct A {
^
testling.c++:14:5: note: candidate function
operator cast_type () const {
^
testling.c++:3:8: note: passing argument to parameter here
struct A {
With reference to the 2011¹ standard: Is clang++ right about rejecting the defaulted code or is g++ right about accepting it?
Nota bene: This is not a question about whether that const qualifier on the cast_type makes sense. This is about which compiler works standard-compliant and only about that.
¹ 2014 should not make a difference here.
EDIT:
Please refrain from re-tagging this with the generic c++ tag.
I'd first like to know which behavior complies to the 2011 standard, and keep the committees' dedication not to break existing (< 2011) code out of ansatz for now.
So it looks like this is covered by this clang bug report rvalue overload hides the const lvalue one? which has the following example:
struct A{};
struct B{operator const A()const;};
void f(A const&);
#ifdef ERR
void f(A&&);
#endif
int main(){
B a;
f(a);
}
which fails with the same error as the OP's code. Richard Smith toward the end says:
Update: we're correct to choose 'f(A&&)', but we're wrong to reject
the initialization of the parameter. Further reduced:
struct A {};
struct B { operator const A(); } b;
A &&a = b;
Here, [dcl.init.ref]p5 bullet 2 bullet 1 bullet 2 does not apply,
because [over.match.ref]p1 finds no candidate conversion functions,
because "A" is not reference-compatible with "const A". So we fall
into [dcl.init.ref]p5 bullet 2 bullet 2, and copy-initialize a
temporary of type A from 'b', and bind the reference to that. I'm not
sure where in that process we go wrong.
but then comes back with another comment due to a defect report 1604:
DR1604 changed the rules so that
A &&a = b;
is now ill-formed. So we're now correct to reject the initialization.
But this is still a terrible answer; I've prodded CWG again. We should
probably discard f(A&&) during overload resolution.
So it seems like clang is technically doing the right thing based on the standard language today but it may change since there seems to be disagreement at least from the clang team that this is the correct outcome. So presumably this will result in a defect report and we will have to wait till it is resolved before we can come to a final conclusion.
Update
Looks like defect report 2077 was filed based on this issue.