I have a problem with a Template function inside a class. When I call "Set" in something() function, VS show me:
Error C2275 'T': illegal use of this type as an expression
The header is:
#include <vector>
#include <array>
#include <iostream>
using t_double = double;
template<typename T>
using t_vec = std::vector<T>;
class SuperPixel2
{
t_vec<double> distances;
template<typename T>
void Set(t_vec<T> &v,
size_t i,
size_t j,
const T &val);
void something();
}
And the cpp file:
#include "SuperPixel2.h"
template<typename T>
void SuperPixel2::Set(t_vec<T> &v,
size_t i,
size_t j,
const T &val)
{
v[i * cols + j] = T;
}
void SuperPixel2::something()
{
t_double d;
//..
Set(distances, k, l, (t_double)d);
//..
}
In addition to what sudo make install said, you generally cannot declare a template in a header file and write the implementation in a cpp file. See here for an answer to your problem.
Well this line looks pretty odd:
v[i * cols + j] = T;
I think it's meant to be:
v[i * cols + j] = val;
As a side note (and maybe this would make more sense looking at the whole class), the type of distances is known (a vector of doubles), so it's unclear to me why the Set method needs to be a templated member.
Related
I am writing simple classes that implement vectors and matrices as part of trying to learn OpenGL. I have matrix and vector classes that look like this :
// Forward declarations
template <typename T, size_t N/*len*/> struct vec;
template<typename T, size_t N /*rows*/, size_t M /*cols*/> struct mat;
// Forward declare *operator for matrix
// (NxM) matrix multiplied by (MxP) matrix yields (NxP) matrix
mat<T, N, P> operator* (const mat<T, N, M>& A, const mat<T, M, P>& B);
template <typename T, size_t N>
struct vec {
public:
vec() {}
virtual ~vec() {}
private:
T[N] m_data;
};
template <typename T, size_t N, size_t M>
struct mat {
public:
mat() {}
virtual ~mat() {}
// This is where it gets interesting. By my reading of the rules
// of C++11, this counts as a partial specialization of the
// operator template, and should not work.
// However, it compiles just fine!
template <size_t n, size_t m, size_t p>
friend mat<T, n, p> operator* (const mat<T, n, m>& A,
const mat<T, m, p> &B);
// Implementation appears later in the same header file.
private:
T[N*M] m_data;
};
I declare the * operator as a friend because I want it to have access to the internal m_data member, but I don't want the users of 'mat' and 'vec' to know the internals.
This compiles and runs just fine. I have a unit test for that matrix multiplication, and it works just fine. However, I don't know why it even compiles, let alone runs. By my reading of the rules of C++ templates, the declaration of the * operator counts as a partial specialization of function template, and is illegal.
What am I missing here?
Turns out this does *NOT* compile. I thought it was compiling because I wasn't invoking the template stream operator in my unit test when I thought I was.
Sorry for the stupid question!
I am trying to use recursion to solve this problem where if i call
decimal<0,0,1>();
i should get the decimal number (4 in this case).
I am trying to use recursion with variadic templates but cannot get it to work.
Here's my code;
template<>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a*2 + decimal<pack...>();
};
int main(int argc, char *argv[]){
cout<<decimal<0,0,1>()<<endl;
return 0;
}
What would be the best way to solve this?
template<typename = void>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a + 2*decimal<pack...>();
};
The problem was with the recursive case, where it expects to be able to call decltype<>(). That is what I have defined in the first overload above. You can essentially ignore the typename=void, the is just necessary to allow the first one to compile.
A possible solution can be the use of a constexpr function (so you can use it's values it's value run-time, when appropriate) where the values are argument of the function.
Something like
#include <iostream>
constexpr int decimal ()
{ return 0; }
template <typename T, typename ... packT>
constexpr int decimal (T const & a, packT ... pack)
{ return a*2 + decimal(pack...); }
int main(int argc, char *argv[])
{
constexpr int val { decimal(0, 0, 1) };
static_assert( val == 2, "!");
std::cout << val << std::endl;
return 0;
}
But I obtain 2, not 4.
Are you sure that your code should return 4?
-- EDIT --
As pointed by aschepler, my example decimal() template function return "eturns twice the sum of its arguments, which is not" what do you want.
Well, with 0, 1, true and false you obtain the same; with other number, you obtain different results.
But you can modify decimal() as follows
template <typename ... packT>
constexpr int decimal (bool a, packT ... pack)
{ return a*2 + decimal(pack...); }
to avoid this problem.
This is a C++14 solution. It is mostly C++11, except for std::integral_sequence nad std::index_sequence, both of which are relatively easy to implement in C++11.
template<bool...bs>
using bools = std::integer_sequence<bool, bs...>;
template<std::uint64_t x>
using uint64 = std::integral_constant< std::uint64_t, x >;
template<std::size_t N>
constexpr uint64< ((std::uint64_t)1) << (std::uint64_t)N > bit{};
template<std::uint64_t... xs>
struct or_bits : uint64<0> {};
template<std::int64_t x0, std::int64_t... xs>
struct or_bits<x0, xs...> : uint64<x0 | or_bits<xs...>{} > {};
template<bool...bs, std::size_t...Is>
constexpr
uint64<
or_bits<
uint64<
bs?bit<Is>:std::uint64_t(0)
>{}...
>{}
>
from_binary( bools<bs...> bits, std::index_sequence<Is...> ) {
(void)bits; // suppress warning
return {};
}
template<bool...bs>
constexpr
auto from_binary( bools<bs...> bits={} )
-> decltype( from_binary( bits, std::make_index_sequence<sizeof...(bs)>{} ) )
{ return {}; }
It generates the resulting value as a type with a constexpr conversion to scalar. This is slightly more powerful than a constexpr function in its "compile-time-ness".
It assumes that the first bit is the most significant bit in the list.
You can use from_binary<1,0,1>() or from_binary( bools<1,0,1>{} ).
Live example.
This particular style of type-based programming results in code that does all of its work in its signature. The bodies consist of return {};.
Is it possible to put the iterator of list in to set:
I wrote codes as follows :
It failed on VS2015 but run smoothly on g++
And I also tried to use std::hash to calculate a hash value of std::list::iterator
but failed again, it has no hash func for iterator.
And one can help ? Or it's impossible .....
#include <set>
#include <list>
#include <cstring>
#include <cassert>
// like std::less
struct myless
{
typedef std::list<int>::iterator first_argument_type;
typedef std::list<int>::iterator second_argument_type;
typedef bool result_type;
bool operator()(const std::list<int>::iterator& x,const std::list<int>::iterator& y) const
{
return memcmp(&x, &y, sizeof(std::list<int>::iterator)) < 0; // using memcmp
}
};
int main()
{
std::list<int> lst = {1,2,3,4,5};
std::set<std::list<int>::iterator,myless> test;
auto it = lst.begin();
test.insert(it++);
test.insert(it++);
assert(test.find(lst.begin()) != test.end()); // fail on vs 2015
auto it1 = lst.end();
auto it2 = lst.end();
assert(memcmp(&it1,&it2,sizeof(it1)) == 0); // fail on vs 2015
system("pause");
return 0;
}
Yes, you can put std::list<T>::iterator in a std::set, if you tell std::set what order they should be in. A reasonable order could be std::less<T>, i.e. you sort the iterators by the values they point to (obviously you then can't insert an std::list::end iterator). Any other order is also OK.
However, you tried to use memcmp, and that is wrong. The predicate used by set requires that equal values compare equal, and there is no guarantee that equal iterators (as defined by list::iterator::operator==) also compare equal using memcmp.
I find a way to do this as like but not for the end iterator
bool operator<(const T& x, const T& y)
{
return &*x < &*y;
}
I'm trying to create a vector of std::function and then pass that vector to a function. I also need to pass arguments to the function objects, so I'm using std::bind. Here is the code:
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void execute(vector<function<void (int)>>& fs) {
for (auto& f : fs)
f();
}
void func(int k) {
cout << "In func " << k << endl;
}
int main()
{
int i = 1;
vector<function<void (int)>> x;
auto f1 = bind(func, i);
//f1(); // this does call intended function
x.push_back(f1);
execute(x);
}
but this gives following error:
function_tmpl.cpp: In function ‘void execute(std::vector >&)’:
function_tmpl.cpp:14:5: error: no match for call to ‘(std::function) ()’
f();
^
In file included from function_tmpl.cpp:1:0:
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2142:11: note: candidate is:
class function
^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2434:5: note: _Res std::function::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {int}]
function::
^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2434:5: note: candidate expects 1 argument, 0 provided
If I call f() inside main(), that works fine, which means that the function has bound with the arguments, but it's not working when passed to another function as argument
You are using a vector of void functions with a single int argument: vector<function<void (int)>>, but you are actually pushing void(void) functions. All you need to do is to change the element type of the vector to vector<function<void (void)>>. Bind works roughly like this:
given:
void f1(int i) { printf("%d", i); }
bind(f1, 1) returns a new function f2:
void f2()
{
f1(1);
}
and since you are pushing f2, the vector should store void(void) functions.
After binding, the type of function has become to void(). So change the type of vector to vector<function<void ()>>, you'll get it.
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void execute(vector<function<void ()>>& fs) {
for (auto& f : fs)
f();
}
void func(int k) {
cout << "In func " << k << endl;
}
int main()
{
int i = 1;
vector<function<void ()>> x;
auto f1 = bind(func, i);
x.push_back(f1);
execute(x);
}
result:
In func 1
LIVE
The return type of std::bind is unspecified. Hence you cannot expect std::bind to return a variable of same type as std::function<void(int)>. Use decltype and templates to resolve.
Here is an example
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template <typename T>
void execute(vector<T>& fs) {
for (auto& f : fs)
f();
}
void func(int k) {
cout << "In func " << k << endl;
}
int main()
{
int i = 1;
auto f1 = bind(func, i);
vector<decltype(f1)> x; //deduce type of f1
x.push_back(f1);
execute(x);
}
f is of type
function<void (int)>&
so the compiler expects you to provide a parameter, like this:
f(1)
Both clang and gcc fail to compile the code below when ArrayCount is a template. This seems wrong, especially in light of the fact that the sizeof ArrayCount solution work. The template version of ArrayCount is normally a better solution, but it's getting in the way here and constexpr is seemingly not living up to the spirit of its promise.
#if 1
template<typename T, size_t N>
constexpr size_t ArrayCount(T (&)[N])
{
return N;
}
// Results in this (clang): error : static_assert expression is not an integral constant expression
// Results in this (gcc): error: non-constant condition for static assertion, 'this' is not a constant expression
#else
#define ArrayCount(t) (sizeof(t) / sizeof(t[0]))
// Succeeds
#endif
struct X
{
int x[4];
X() { static_assert(ArrayCount(x) == 4, "should never fail"); }
};
The right solution doesn't use homebrew code, but a simple type trait:
int a[] = {1, 2, 3};
#include <type_traits>
static_assert(std::extent<decltype(a)>::value == 3, "You won't see this");
It makes sense to me that this code would fail to compile since ArrayCount is a function taking a non-constexpr argument. According to the standard, I believe this means that ArrayCount must be intstantiated as a non-constexpr function.
There are workarounds, of course. I can think of two off the top of my head (one implemented in terms of the other):
template<typename T> struct ArrayCount;
template<typename T, size_t N>
struct ArrayCount<T[N]> {
static size_t const size = N;
};
template<typename T>
constexpr size_t ArrayCount2() {
return ArrayCount<T>::size;
}
struct X {
int x[4];
X() {
static_assert(ArrayCount<decltype(x)>::size == 4, "should never fail");
static_assert(ArrayCount2<decltype(x)>() == 4, "should never fail");
}
};
It does mean having to use decltype() when you might not wish to, but it does break the pro-forma constraint on taking a non-constexpr parameter.