I want to set default class type as default comparison type in Template and then I want to compares two character strings using templates, I did write code but it’s giving error. Code and error is given below,
class CaseSenCmp{
public:
static int isEqual(char x, char y){ return x==y; }
};
template<typename c=CaseSenCmp>
int compare(char* str1, char* str2){
for(int i=0; i<strlen(str1) && i<strlen(str2); i++)
if(!c::isEqual(str1[i], str2[i]))
return str1[i]-str2[i];
return strlen(str1)-strlen(str2);
}
main(){
char *x = "hello", *y = "HELLO";
compare(x,y);
}
But when i have added this prototype of template, it works
template<typename c>
Compiler gives this error
error: default template arguments may not be used in function templates without -std=c++11 or -std=gnu++11|
Also when i try to do type casting in main function using this code, it also works
compare<CaseSenCmp>(x,y);
But i want to set Default Policy
I also faced this issue in code::blocks. To tackle this issue you have to enable
-std=c++11
into the you compiler. In case of code::blocks you have to follow given below instructions.
Settings->Compiler->Compiler Flags...Look for and check the option to "Have g++ follow the C++11 ISO C++ language standard". If that doesn't get it then also check the box above it for the C++0x standard.
Add -std=c++11 to compilation flags, because another way it won't compile.
Related
TL;DR
Before you attempt to read this whole post, know that:
a solution to the presented issue has been found by myself, but I'm still eager to know if the analysis is correct;
I've packaged the solution into a fameta::counter class that solves a few remaining quirks. You can find it on github;
you can see it at work on godbolt.
How it all started
Since Filip Roséen discovered/invented, in 2015, the black magic that compile time counters via friend injection are in C++, I have been mildly obsessed with the device, so when the CWG decided that functionality had to go I was disappointed, but still hopeful that their mind could be changed by showing them a few compelling use cases.
Then, a couple years ago I decided to have a look at the thing again, so that uberswitches could be nested - an interesting use case, in my opinion - only to discover that it wouldn't work any longer with the new versions of the available compilers, even though issue 2118 was (and still is) in open state: the code would compile, but the counter would not increase.
The problem has been reported on Roséen's website and recently also on stackoverflow: Does C++ support compile-time counters?
A few days ago I decided to try and tackle the issues again
I wanted to understand what had changed in the compilers that made the, seemingly still valid C++, not work any longer. To that end, I've searched wide and far the interweb for somebody to have talked about it, but to no avail. So I've begun experimenting and came to some conclusions, that I'm presenting here hoping to get a feedback from the more-knowledged-than-myself around here.
Below I'm presenting Roséen's original code for sake of clarity. For an explanation of how it works, please refer to his website:
template<int N>
struct flag {
friend constexpr int adl_flag (flag<N>);
};
template<int N>
struct writer {
friend constexpr int adl_flag (flag<N>) {
return N;
}
static constexpr int value = N;
};
template<int N, int = adl_flag (flag<N> {})>
int constexpr reader (int, flag<N>) {
return N;
}
template<int N>
int constexpr reader (float, flag<N>, int R = reader (0, flag<N-1> {})) {
return R;
}
int constexpr reader (float, flag<0>) {
return 0;
}
template<int N = 1>
int constexpr next (int R = writer<reader (0, flag<32> {}) + N>::value) {
return R;
}
int main () {
constexpr int a = next ();
constexpr int b = next ();
constexpr int c = next ();
static_assert (a == 1 && b == a+1 && c == b+1, "try again");
}
With both g++ and clang++ recent-ish compilers, next() always returns 1. Having experimented a bit, the issue at least with g++ seems to be that once the compiler evaluates the functions templates default parameters the first time the functions are called, any subsequent call to those functions doesn't trigger a re-evaluation of the default parameters, thus never instantiating new functions but always referring to the previously instantiated ones.
First questions
Do you actually agree with this diagnosis of mine?
If yes, is this new behavior mandated by the standard? Was the previous one a bug?
If not, then what is the problem?
Keeping the above in mind, I came up with a work around: mark each next() invokation with a monotonically increasing unique id, to pass onto the callees, so that no call would be the same, therefore forcing the compiler to re-evaluate all the arguments each time.
It seems a burden to do that, but thinking of it one could just use the standard __LINE__ or __COUNTER__-like (wherever available) macros, hidden in a counter_next() function-like macro.
So I came up with the following, that I present in the most simplified form that shows the problem I will talk about later.
template <int N>
struct slot;
template <int N>
struct slot {
friend constexpr auto counter(slot<N>);
};
template <>
struct slot<0> {
friend constexpr auto counter(slot<0>) {
return 0;
}
};
template <int N, int I>
struct writer {
friend constexpr auto counter(slot<N>) {
return I;
}
static constexpr int value = I-1;
};
template <int N, typename = decltype(counter(slot<N>()))>
constexpr int reader(int, slot<N>, int R = counter(slot<N>())) {
return R;
};
template <int N>
constexpr int reader(float, slot<N>, int R = reader(0, slot<N-1>())) {
return R;
};
template <int N>
constexpr int next(int R = writer<N, reader(0, slot<N>())+1>::value) {
return R;
}
int a = next<11>();
int b = next<34>();
int c = next<57>();
int d = next<80>();
You can observe the results of the above on godbolt, which I've screenshotted for the lazies.
And as you can see, with trunk g++ and clang++ until 7.0.0 it works!, the counter increases from 0 to 3 as expected, but with clang++ version above 7.0.0 it doesn't.
To add insult to injury, I've actually managed to make clang++ up to version 7.0.0 crash, by simply adding a "context" parameter to the mix, such that the counter is actually bound to that context and, as such, can be restarted any time a new context is defined, which opens up for the possibility to use a potentially infinite amount of counters. With this variant, clang++ above version 7.0.0 doen't crash, but still doesn't produce the expected result. Live on godbolt.
At loss of any clue about what was going on, I've discovered the cppinsights.io website, that lets one see how and when templates get instantiated. Using that service what I think is happening is that clang++ does not actually define any of the friend constexpr auto counter(slot<N>) functions whenever writer<N, I> is instantiated.
Trying to explicitly call counter(slot<N>) for any given N that should already have been instantiated seems to give basis to this hypothesis.
However, if I try to explicitly instantiate writer<N, I> for any given N and I that should have already been instantiated, then clang++ complains about a redefined friend constexpr auto counter(slot<N>).
To test the above, I've added two more lines to the previous source code.
int test1 = counter(slot<11>());
int test2 = writer<11,0>::value;
You can see it all for yourself on godbolt. Screenshot below.
So, it appears that clang++ believes it has defined something that it believes it hasn't defined, which kind of makes your head spin, doesn't it?
Second batch of questions
Is my workaround legal C++ at all, or did I manage to just discover another g++ bug?
If it's legal, did I therefore discover some nasty clang++ bugs?
Or did I just delve into the dark underworld of Undefined Behavior, so I myself am the only one to blame?
In any event, I would warmly welcome anybody who wanted to help me get out of this rabbit hole, dispensing headaching explanations if need be. :D
After further investigation, it turns out there exists a minor modification that can be performed to the next() function, which makes the code work properly on clang++ versions above 7.0.0, but makes it stop working for all other clang++ versions.
Have a look at the following code, taken from my previous solution.
template <int N>
constexpr int next(int R = writer<N, reader(0, slot<N>())+1>::value) {
return R;
}
If you pay attention to it, what it literally does is to try to read the value associated with slot<N>, add 1 to it and then associate this new value to the very same slot<N>.
When slot<N> has no associated value, the value associated with slot<Y> is retrieved instead, with Y being the highest index less than N such that slot<Y> has an associated value.
The problem with the above code is that, even though it works on g++, clang++ (rightfully, I would say?) makes reader(0, slot<N>()) permanently return whatever it returned when slot<N> had no associated value. In turn, this means that all slots get effectively associated with the base value 0.
The solution is to transform the above code into this one:
template <int N>
constexpr int next(int R = writer<N, reader(0, slot<N-1>())+1>::value) {
return R;
}
Notice that slot<N>() has been modified into slot<N-1>(). It makes sense: if I want to associate a value to slot<N>, it means no value is associated yet, therefore it makes no sense to attempt to retrieve it. Also, we want to increase a counter, and value of the counter associated with slot<N> has to be one plus the value associated with slot<N-1>.
Eureka!
This breaks clang++ versions <= 7.0.0, though.
Conclusions
It seems to me that the original solution I posted has a conceptual bug, such that:
g++ has quirk/bug/relaxation that cancels out with my solution's bug and eventually makes the code work nonetheless.
clang++ versions > 7.0.0 are stricter and don't like the bug in the original code.
clang++ versions <= 7.0.0 have a bug that makes the corrected solution not work.
Summing all that up, the following code works on all versions of g++ and clang++.
#if !defined(__clang_major__) || __clang_major__ > 7
template <int N>
constexpr int next(int R = writer<N, reader(0, slot<N-1>())+1>::value) {
return R;
}
#else
template <int N>
constexpr int next(int R = writer<N, reader(0, slot<N>())+1>::value) {
return R;
}
#endif
The code as-is also works with msvc.
The icc compiler doesn't trigger SFINAE when using decltype(counter(slot<N>())), preferring to complain about not being able to deduce the return type of function "counter(slot<N>)" because it has not been defined. I believe this is a bug, that can be worked around by doing SFINAE on the direct result of counter(slot<N>). This works on all other compilers too, but g++ decides to spit out a copious amount of very annoying warnings that cannot be turned off. So, also in this case, #ifdef could come to the rescue.
The proof is on godbolt, screnshotted below.
I have written a small wrapper for typeinfo to get the typecode of a variable at compile time more easily:
template<typename DataType>
class TypeInfo
{
public:
static const char* typecode()
{
DataType TypedVariable = 0;
const char* code = typeid(TypedVariable).name();
return(code);
};
};
I use it like this:
const char* code = TypeInfo<float>::typecode();
It compiles perfectly fine and works as expected, but I am getting the warning
src/common.hh(153): warning: variable "TypedVariable" was set but never used
detected during:
instantiation of "char TypeInfo<DataType>::typecode() [with DataType=r32]"
...
I am wondering why "calling" typeid() on a variable does not count as using it. I know that it is a defined keyword, but still I am irritated that getting the type of a variable does not count as using it.
The compilation is done using nvcc of CUDA 9.2. Maybe it is a CUDA specific thing?
Thanks for any help :)
//edit:
I made a mistake by not returning the full char* because I use only normal types! Thanks for making me aware of the typo! I also added the template definition. I forgot to copy that over!
Because you don't use the value of TypedVariable. You just use its type (and you can get it's type by rewriting your initialization as:
char const * const code = typeid(DataType).name();
Is there any way to invoke a user defined literal on lvalues?
e.g I would like to
int operator "" _xor1(int a) { return a^1; }
// Works fine
17_xor1;
auto myint = get_something_only_availabe_at_runtime();
// Any way to use _xor1 on myint?
_xor1(myint); // Doesn't work
Also, when compiling the following code at the compiler explorer, I was surprised to discover that it was all resolved at runtime, although all data is available at compile time. Why is that?
constexpr int operator "" _xor1(unsigned long long a) {
return a^1;
}
int main() {
// This code resolves the user defined literal at runtime on gcc,
// msvc and clang - I don't see why I can't use the
// user defined literal at runtime?
return 17_xor1;
}
I'm not sure you really want to - as commented, you're probably better off defining a normal function and calling that - but you can call it using:
operator""_xor1(myInt);
See User-defined literals for more information.
No, you cannot invoke a user-defined literal on a variable populated at runtime. Nor do you need to. Just define a standalone function that different pieces of code can invoke when needed, eg:
template <typename T>
T do_xor1(T a) { return a^1; }
int operator "" _xor1(unsigned long long a) { return do_xor1(a); }
// Works fine
17_xor1;
auto myint = get_something_only_availabe_at_runtime();
do_xor1(myint);
I can't use non-primitive types as keys for associative arrays; attempting to do so will result in the following error on the line where I define the AA:
Error: AA key type MyString does not have 'bool opEquals(ref const MyString) const
I first discovered this when using the type CollisionHandler[Tuple!(TypeInfo, TypeInfo)] where CollisionHandler is an alias for a function pointer type.
However, even the example code from the "Using Structs or Unions as the KeyType" heading under the Associative array documentation page fails with the same error:
import std.string;
struct MyString
{
string str;
size_t toHash() const #safe pure nothrow
{
size_t hash;
foreach (char c; str)
hash = (hash * 9) + c;
return hash;
}
// opEquals defined here?
bool opEquals(ref const MyString s) const #safe pure nothrow
{
return std.string.cmp(this.str, s.str) == 0;
}
}
int[MyString] foo; // errors here
void main() {
}
Here, MyString.opEquals is defined and should have the proper signature, yet the dmd compiler says that it isn't implemented. The fact that this snippet comes straight from the docs makes me suspect it's a compiler bug, but maybe I'm just missing something?
Running DMD under Linux, but the issue also happens under Windows 7. DMD version:
$ dmd --help
DMD64 D Compiler v2.066.1
Copyright (c) 1999-2014 by Digital Mars written by Walter Bright
Documentation: http://dlang.org/
...
This is a case of a misleading error message emitted by the compiler.
The problem is with the #safe annotation on the opEquals method. In 2.066.1, std.string.cmp is not #safe - however, the compiler displays the wrong error message. If you rename opEquals to something else, e.g. foo, you'll get a different error message:
test.d(19): Error: safe function 'test.MyString.foo' cannot call system function
'std.algorithm.cmp!("a < b", string, string).cmp'
The workaround is to remove #safe, or replace it with #trusted.
Note that this problem does not manifest in the development version of DMD, so it should be fixed in 2.067.0.
Certain situations in my code, I end up invoking the function only if that function is defined, or else I should not. How can I achieve this?
like:
if (function 'sum' exists ) then invoke sum ()
Maybe the other way around to ask this question is how to determine if function is defined at runtime and if so, then invoke?
When you declare 'sum' you could declare it like:
#define SUM_EXISTS
int sum(std::vector<int>& addMeUp) {
...
}
Then when you come to use it you could go:
#ifdef SUM_EXISTS
int result = sum(x);
...
#endif
I'm guessing you're coming from a scripting language where things are all done at runtime. The main thing to remember with C++ is the two phases:
Compile time
Preprocessor runs
template code is turned into real source code
source code is turned in machine code
runtime
the machine code is run
So all the #define and things like that happen at compile time.
....
If you really wanted to do it all at runtime .. you might be interested in using some of the component architecture products out there.
Or maybe a plugin kind of architecture is what you're after.
Using GCC you can:
void func(int argc, char *argv[]) __attribute__((weak)); // weak declaration must always be present
// optional definition:
/*void func(int argc, char *argv[]) {
printf("FOUND THE FUNCTION\n");
for(int aa = 0; aa < argc; aa++){
printf("arg %d = %s \n", aa, argv[aa]);
}
}*/
int main(int argc, char *argv[]) {
if (func){
func(argc, argv);
} else {
printf("did not find the function\n");
}
}
If you uncomment func it will run it otherwise it will print "did not find the function\n".
While other replies are helpful advices (dlsym, function pointers, ...), you cannot compile C++ code referring to a function which does not exist. At minimum, the function has to be declared; if it is not, your code won't compile. If nothing (a compilation unit, some object file, some library) defines the function, the linker would complain (unless it is weak, see below).
But you should really explain why you are asking that. I can't guess, and there is some way to achieve your unstated goal.
Notice that dlsym often requires functions without name mangling, i.e. declared as extern "C".
If coding on Linux with GCC, you might also use the weak function attribute in declarations. The linker would then set undefined weak symbols to null.
addenda
If you are getting the function name from some input, you should be aware that only a subset of functions should be callable that way (if you call an arbitrary function without care, it will crash!) and you'll better explicitly construct that subset. You could then use a std::map, or dlsym (with each function in the subset declared extern "C"). Notice that dlopen with a NULL path gives a handle to the main program, which you should link with -rdynamic to have it work correctly.
You really want to call by their name only a suitably defined subset of functions. For instance, you probably don't want to call this way abort, exit, or fork.
NB. If you know dynamically the signature of the called function, you might want to use libffi to call it.
I suspect that the poster was actually looking for something more along the lines of SFINAE checking/dispatch. With C++ templates, can define to template functions, one which calls the desired function (if it exists) and one that does nothing (if the function does not exist). You can then make the first template depend on the desired function, such that the template is ill-formed when the function does not exist. This is valid because in C++ template substitution failure is not an error (SFINAE), so the compiler will just fall back to the second case (which for instance could do nothing).
See here for an excellent example: Is it possible to write a template to check for a function's existence?
use pointers to functions.
//initialize
typedef void (*PF)();
std::map<std::string, PF> defined_functions;
defined_functions["foo"]=&foo;
defined_functions["bar"]=&bar;
//if defined, invoke it
if(defined_functions.find("foo") != defined_functions.end())
{
defined_functions["foo"]();
}
If you know what library the function you'd like to call is in, then you can use dlsym() and dlerror() to find out whether or not it's there, and what the pointer to the function is.
Edit: I probably wouldn't actually use this approach - instead I would recommend Matiu's solution, as I think it's much better practice. However, dlsym() isn't very well known, so I thought I'd point it out.
You can use #pragma weak for the compilers that support it (see the weak symbol wikipedia entry).
This example and comment is from The Inside Story on Shared Libraries and Dynamic Loading:
#pragma weak debug
extern void debug(void);
void (*debugfunc)(void) = debug;
int main() {
printf(“Hello World\n”);
if (debugfunc) (*debugfunc)();
}
you can use the weak pragma to force the linker to ignore unresolved
symbols [..] the program compiles and links whether or not debug()
is actually defined in any object file. When the symbol remains
undefined, the linker usually replaces its value with 0. So, this
technique can be a useful way for a program to invoke optional code
that does not require recompiling the entire application.
So another way, if you're using c++11 would be to use functors:
You'll need to put this at the start of your file:
#include <functional>
The type of a functor is declared in this format:
std::function< return_type (param1_type, param2_type) >
You could add a variable that holds a functor for sum like this:
std::function<int(const std::vector<int>&)> sum;
To make things easy, let shorten the param type:
using Numbers = const std::vectorn<int>&;
Then you could fill in the functor var with any one of:
A lambda:
sum = [](Numbers x) { return std::accumulate(x.cbegin(), x.cend(), 0); } // std::accumulate comes from #include <numeric>
A function pointer:
int myFunc(Numbers nums) {
int result = 0;
for (int i : nums)
result += i;
return result;
}
sum = &myFunc;
Something that 'bind' has created:
struct Adder {
int startNumber = 6;
int doAdding(Numbers nums) {
int result = 0;
for (int i : nums)
result += i;
return result;
}
};
...
Adder myAdder{2}; // Make an adder that starts at two
sum = std::bind(&Adder::doAdding, myAdder);
Then finally to use it, it's a simple if statement:
if (sum)
return sum(x);
In summary, functors are the new pointer to a function, however they're more versatile. May actually be inlined if the compiler is sure enough, but generally are the same as a function pointer.
When combined with std::bind and lambda's they're quite superior to old style C function pointers.
But remember they work in c++11 and above environments. (Not in C or C++03).
In C++, a modified version of the trick for checking if a member exists should give you what you're looking for, at compile time instead of runtime:
#include <iostream>
#include <type_traits>
namespace
{
template <class T, template <class...> class Test>
struct exists
{
template<class U>
static std::true_type check(Test<U>*);
template<class U>
static std::false_type check(...);
static constexpr bool value = decltype(check<T>(0))::value;
};
template<class U, class = decltype(sum(std::declval<U>(), std::declval<U>()))>
struct sum_test{};
template <class T>
void validate_sum()
{
if constexpr (exists<T, sum_test>::value)
{
std::cout << "sum exists for type " << typeid(T).name() << '\n';
}
else
{
std::cout << "sum does not exist for type " << typeid(T).name() << '\n';
}
}
class A {};
class B {};
void sum(const A& l, const A& r); // we only need to declare the function, not define it
}
int main(int, const char**)
{
validate_sum<A>();
validate_sum<B>();
}
Here's the output using clang:
sum exists for type N12_GLOBAL__N_11AE
sum does not exist for type N12_GLOBAL__N_11BE
I should point out that weird things happened when I used an int instead of A (sum() has to be declared before sum_test for the exists to work, so maybe exists isn't the right name for this). Some kind of template expansion that didn't seem to cause problems when I used A. Gonna guess it's ADL-related.
This answer is for global functions, as a complement to the other answers on testing methods. This answer only applies to global functions.
First, provide a fallback dummy function in a separate namespace. Then determine the return type of the function-call, inside a template parameter. According to the return-type, determine if this is the fallback function or the wanted function.
If you are forbidden to add anything in the namespace of the function, such as the case for std::, then you should use ADL to find the right function in the test.
For example, std::reduce() is part of c++17, but early gcc compilers, which should support c++17, don't define std::reduce(). The following code can detect at compile-time whether or not std::reduce is declared. See it work correctly in both cases, in compile explorer.
#include <numeric>
namespace fallback
{
// fallback
std::false_type reduce(...) { return {}; }
// Depending on
// std::recuce(Iter from, Iter to) -> decltype(*from)
// we know that a call to std::reduce(T*, T*) returns T
template <typename T, typename Ret = decltype(reduce(std::declval<T*>(), std::declval<T*>()))>
using return_of_reduce = Ret;
// Note that due to ADL, std::reduce is called although we don't explicitly call std::reduce().
// This is critical, since we are not allowed to define any of the above inside std::
}
using has_reduce = fallback::return_of_reduce<std::true_type>;
// using has_sum = std::conditional_t<std::is_same_v<fallback::return_of_sum<std::true_type>,
// std::false_type>,
// std::false_type,
// std::true_type>;
#include <iterator>
int main()
{
if constexpr (has_reduce::value)
{
// must have those, so that the compile will find the fallback
// function if the correct one is undefined (even if it never
// generates this code).
using namespace std;
using namespace fallback;
int values[] = {1,2,3};
return reduce(std::begin(values), std::end(values));
}
return -1;
}
In cases, unlike the above example, when you can't control the return-type, you can use other methods, such as std::is_same and std::contitional.
For example, assume you want to test if function int sum(int, int) is declared in the current compilation unit. Create, in a similar fashion, test_sum_ns::return_of_sum. If the function exists, it will be int and std::false_type otherwise (or any other special type you like).
using has_sum = std::conditional_t<std::is_same_v<test_sum_ns::return_of_sum,
std::false_type>,
std::false_type,
std::true_type>;
Then you can use that type:
if constexpr (has_sum::value)
{
int result;
{
using namespace fallback; // limit this only to the call, if possible.
result = sum(1,2);
}
std::cout << "sum(1,2) = " << result << '\n';
}
NOTE: You must have to have using namespace, otherwise the compiler will not find the fallback function inside the if constexpr and will complain. In general, you should avoid using namespace since future changes in the symbols inside the namespace may break your code. In this case there is no other way around it, so at least limit it to the smallest scope possible, as in the above example