Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm very confused as to why Terminal is telling me that thehash2 is not a template when I try to compile.
Am I crazy?
template<typename Symbol>
class thehash
{
public:
size_t operator()(const Symbol & item)
{
static thehash2<string> hf;
return hf(item.getData());
}
};
template<typename string>
class thehash2<string>
{
public:
size_t operator()(const string & key)
{
size_t hashVal = 0;
for(char ch : key)
hashVal = 37 * hashVal + ch;
return hashVal;
}
};
template<typename string>
class thehash2<string>
{
Here's an error. You might wanted to write:
template<typename T>
class thehash2
{
Note, that - as stated in comments - you shouldn't use string as a typename in template. Most common names for template parameters are usually single letters - T, U, ... such that they won't be easily confused with real type names.
Second option:
class thehash2 : public thehash<std::string>
{
(depending on your actual needs)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
Improve this question
With this nice simplified compile time string class.
There are no constexpr/consteval function parameters in C++
but the point of this question is:
Can I get a function call style for passing of non-type template parameters ?
With the suffix I can get pretty close.
But can it be done better ?
I do not want to use this syntax
test_normal_function2<"asd">(x);
How can I get rid of _fs suffix in the invocation of test_normal_function ?
#include <algorithm>
struct no_init_fixed_string {};
template <std::size_t N>
struct fixed_string
{
constexpr fixed_string(const char (&foo)[N + 1])
{
std::copy_n(foo, N + 1, data.begin());
}
std::array<char, N + 1> data{};
constexpr fixed_string(no_init_fixed_string)
: data{}
{
}
};
template <std::size_t N>
fixed_string(const char (&str)[N]) -> fixed_string<N - 1>;
template<fixed_string s>
struct fixed_string_type
{
};
template<fixed_string s>
constexpr auto operator"" _fs()
{
return fixed_string_type<s>{};
}
template<fixed_string s>
void test_normal_function(fixed_string_type<s>, int x )
{
//use s as consexpr parameter
}
template<fixed_string s>
void test_normal_function2( int x )
{
}
int main()
{
int x = 3;
test_normal_function("asd"_fs,x); //this works
test_normal_function2<"asd">(x); // this works but its ugly
//test_normal_function("asd",x); //this doesn't compile but its pretty.
}
How can I make call to test_normal_function work without _fs suffix ?
Preprocessor macro trickery aside, it is impossible to do it with the exact syntax you want, because a usual string literal (not a user-defined literal) does never encode its value in its type (only its length).
A value passed to a function via a function parameter can never be used by the function in a constant expression. Only information in the type can be used that way.
However, you can pass a value via a template parameter and make use of it in a constant expression:
test_normal_function<"asd">({},x);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm trying to build a static array of dynamic arrays...at compile time. Some examples:
struct Apple {
int x;
};
struct Pear {
int a, b;
};
then...
Registry<Apple, Pear> registry;
auto appleId = registry.add<Apple>(1);
auto pearId = registry.add<Pear>(1, 2);
Apple* apple = registry.get<Apple>(appleId);
or...
Registry registry;
registry.register<Apple>();
registry.register<Pear>();
...although the second example would probably be even harder to do at compile time.
I would assume that the data structure inside looks like this:
template <typename... Ts>
struct Registry {
std::array<std::vector<?>, sizeof...(Ts)> values;
};
Any ideas on how to start exploring this problem?
std::vector can only contain elements of the same type. std::tuple, on the other hand, can contain elements of different types:
template<typename... Ts>
struct Registry {
std::tuple<std::vector<Ts>...> values;
template<class T, class... Args>
size_t add(Args&&... args) {
auto& v = std::get<std::vector<T>>(values);
auto idx = v.size();
v.emplace_back(std::forward<Args>(args)...);
return idx;
}
template<class T>
T* get(size_t idx) {
auto& v = std::get<std::vector<T>>(values);
return idx < v.size() ? &v[idx] : 0;
}
};
int main() {
Registry<Apple, Pear> registry;
auto appleId = registry.add<Apple>(1);
auto pearId = registry.add<Pear>(1, 2);
Apple* apple = registry.get<Apple>(appleId);
}
However, manipulating such Registry in C++17 is run-time only.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
This is the error I'm getting " C++ requires a type specifier for all declarations" I don't know how to fix it
//this code id in the DynamicStringArray.cpp
template<class T>
DynamicArray<T>:: operator = (const DynamicArray<T> &rightSide) {
if(this != &rightSide) {
delete[] dynamicArray;
dynamicArray = new T[rightSide.size];
size = rightSide.size;
for(int i = 0; i < size; i++) {
dynamicArray[i] = rightSide.dynamicArray[i];
}
}
//and this one is in the DynamicStringArray.h
template <class T>
class DynamicArray{
public:
DynamicArray<T> operator=(const DynamicArray &rightSide);
exit status 1
DynamicStringArray.cpp:64:19: error: C++ requires a type specifier for all declarations
DynamicArray:: operator = (const DynamicArray &rightSide) {
^
1 error generated.
" C++ requires a type specifier for all declarations" I don't know how
to fix it
You fix this problem by adding a type specifier to your declaration. What does the function
template<class T>
DynamicArray<T>:: operator = (...)
return? Probably not an int or float or bool, right? The compiler does not know because you did not identify what the return type is.
Here is an example (I found in SO!):
// In MyClass.h
MyClass<T>& operator+=(const MyClass<T>& classObj);
// In MyClass.cpp
template <class T>
MyClass<T>& MyClass<T>::operator+=(const MyClass<T>& classObj) {
// ...
return *this;
}
In both cases, the return type specifier is simply:
MyClass<T>&
Hope this helps.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have some code which std::to_string()'s a variable whose type is a template parameter. Suppose the code is:
template <typename T>
std::string foo(const T& t) {
return std::string("I got ") + std::to_string(t);
}
Now, sometimes this parameter needs to be a void *; and I would like to get the address in the string, e.g. "I got 0xdeadbeef". No problem, right? I should get it just the same as if I did std::cout << my_ptr, right? ... Unfortunately for me, that's not the case. Well,
Is it "legitimate" for me to want the code above to work as I described?
Other than insisting on the use of a stream in foo(), is there anything better to do than to overload std::to_string for void*'s (using an std::stringstream in there for the operator<<) ?
namespace my_to_str {
using std::to_string;
std::string to_string(void* ptr){
// implement
}
}
Now my_to_str::to_string can be extended with your own set of overloads, like void*.
You can't overload std::to_string() for void*, so that's moot.
But you don't have to use std::to_string(). You could implement your own that just falls back to using a stringstream:
namespace N {
template <class T>
auto to_string(T const& val, int)
-> decltype(std::to_string(val))
{
return std::to_string(val);
}
template <class T>
std::string to_string(T const& val, ...)
{
std::ostringstream oss;
oss << val;
return oss.str();
}
template <class T>
std::string to_string(T const& val) {
return to_string(val, 0);
}
}
And this does allow for overloading N::to_string() with whatever specifics you want (e.g. if you want N::to_string(void* ) to do something special, just add another overload).
You can make custom operator+ for void * cases:
std::string operator+(const std::string &str, const void *vstr){
return str + std::string(reinterpret_cast<const char *>(vstr));
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Some may have noticed that std::hash does not support tuples. So I added an overload which just seems "nicer" than the solution I saw up till now. Anyone got ideas to further cut down this code? Please note that this is a compiler killer! The only one that could compile it was "Clang 3.2"... Intel Compiler 13.1 does not get the specialization and keeps telling "C++ standard does not support hash blabla". And we don't need to talk about the original Microsoft compiler do we.
BTW, my solution supports recursive tuples like std::tuple<std::tuple<int,int>,int> so I am not sure if this also applies to the existing solutions I saw this day.
namespace std
{
template<typename... TTypes>
class hash<std::tuple<TTypes...>>
{
private:
typedef std::tuple<TTypes...> Tuple;
template<int N>
size_t operator()(Tuple value) const { return 0; }
template<int N, typename THead, typename... TTail>
size_t operator()(Tuple value) const
{
constexpr int Index = N - sizeof...(TTail) - 1;
return hash<THead>()(std::get<Index>(value)) ^ operator()<N, TTail...>(value);
}
public:
size_t operator()(Tuple value) const
{
return operator()<sizeof...(TTypes), TTypes...>(value);
}
};
}
Quite obvious once you've seen it:
template<int N, typename THead, typename... TTail>
size_t operator()(Tuple value) const
{
constexpr int Index = N - sizeof...(TTail) - 1;
return hash<THead>()(std::get<Index>(value)) ^ operator()<N, TTail...>(value);
}