What NS should user libraries be in? - c++

This is a continuation of my question here: Why isn't std::begin/end being considered here?
I'm in the midst of moving my custom library code into namespace Toolbox - including both contains template and begin and end for CStringA and CStringW.
I have a template free function algorithm "contains":
namespace Toolbox {
template <typename collection_type, typename element_type, typename comparison_function_type>
bool contains(const collection_type & collection, const element_type & element, comparison_function_type comparison_function)
{
using namespace ::std;
return end(collection) != find_if(begin(collection), end(collection), [&](const element_type & candidate) { return comparison_function(candidate, element); });
}
} // NS
This works for the following or fails for the following depending on what's in scope (the following is at global NS):
static const TCHAR * kPackFiles[] = { _T("boxit"), _T("pack") };
const auto & name = filename.GetName();
if (contains(kPackFiles, name, Toolbox::case_insensitive_equal_to<Toolbox::TCHARStringPolicy>()))
do_something_interesting();
The above compiles unless the following is in scope:
namespace Toolbox {
template <typename T>
const typename ::std::enable_if<::std::is_same<T, CStringA>::value || ::std::is_same<T, CStringW>::value, T>::type::XCHAR *
begin(const T & str) { return str.GetString(); }
template <typename T>
const typename ::std::enable_if<::std::is_same<T, CStringA>::value || ::std::is_same<T, CStringW>::value, T>::type::XCHAR *
end(const T & str) { return str.GetString() + str.GetLength(); }
} // NS Toolbox
The above is intended to extend CStringA and CStringW to offer const char_type iterators on them. This generally works for other scenarios such as for (c : my_cstring) cout << c;
But if my begin and end overloads for CString are in scope, then the compiler won't even consider anything in std namespace! Ugh!
So I am at a loss as to how the NS system is intended to work practically - I see the rules (now) - it only considers the nearest NS and if anything there can be made to match (despite apparently SFINAE) then the compiler stops looking and the block just fails to compile. :(
I need some way to have my library introduce classes / free functions / algorithms / types in a way that still allows for std namespace to be considered when trying to resolve overloads such as begin and end in the above example!
And I'm at a loss here.
I can certainly move all of my algorithms - such as contains out to global NS. But now I feel like I'm making a mistake - weren't NSes supposed to address (unintended) name collisions explicitly? But if I move my algorithms into global NS I'm "polluting" the global NS, and if I put them into a library NS then I'm at odds with the very NS rules that were - I thought - intended to break out of this problem?
My goal would be to be able to give clients full control of what is eligible at any given time for consideration - and not have that pre-decided by my library, but with default fall-backs so that - in this contains example, if the user doesn't have a better customization of begin/end for the data type involved, that a sensible default be used. NOT stop at some other library extensions and say "Whatever, I (the compiler) give up."
I need it to continue to searching until it either finds a working match or there aren't any at all.
So:
1. did I mess up the SFINAE in my definitions of begin/end for CStrings?
2. If I didn't mess that up and SFINAE is working as intended, then how do I make NSes work for me instead of against me?
Thanks for any assistance you might offer!

Related

static_assert inside template or class, gotcha

On this subject, I have read few relevant SO questions/answers/comments. Found only one relevant but somewhat buried question/answer here. Allow me to try and clearly show the issue in question/answer manner. For the benefit of others.
Let the code speak. imagine you design this template.
// value holder V1.0
// T must not be reference or array or both
template<typename T> struct no_arrf_naive
{
static_assert(!std::is_reference_v<T>, "\n\nNo references!\n\n");
static_assert(!std::is_array_v<T>, "\n\nNo arrays!\n\n");
using value_type = T;
T value;
};
Simple and safe, one might think. Some time after, other folks take this complex large API, where this is buried deep, and start using it. The struct above is deep inside. As usually, they just use it, without looking into the code behind.
using arf = int(&)[3];
using naivete = no_arrf_naive<arf>;
// the "test" works
constexpr bool is_ok_type = std::is_class_v< naivete >;
// this declaration will also "work"
void important ( naivete ) ;
But. Instantiations do not work
naivete no_compile;
static assert message does show all of a sudden. But how has the "test" compiled and passed? What is going on here?
The issue is that API is wrong. static_assert as class member does "kick-in" but not before instantiation.
First the offending API commented
template<typename T>
struct no_arrf_naive
{
// member declarations
// used only on implicit instantiation
// https://en.cppreference.com/w/cpp/language/class_template#Implicit_instantiation
static_assert(!std::is_reference_v<T>, "\n\nNo references!\n\n");
static_assert(!std::is_array_v<T>, "\n\nNo arrays!\n\n");
using value_type = T;
T value;
};
Users are here properly coding to transform from Template to Type, but, static_assert's do not kick-in:
using naivete = no_arrf_naive<arf>;
This might most worryingly go on unnoticed, until someone wants to use this. That will not compile and the message, API author has placed in there, will show at last. But alas, too late.
And on projects laboring on some large C++ source, problems that show up late, are the most notorious ones.
The solution is good old SFINAE. The API fixed is this:
// value holder
// references or arrays or both are excluded at compile time
template<typename T,
std::enable_if_t<
(!std::is_reference_v<T> && !std::is_array_v<T>), bool> = true
> struct no_arrf
{
using value_type = T;
T value;
};
The above will not compile immediately upon trying to create the type from template with either reference or array or both:
// reference to array of three int's
using arf = int(&)[3] ;
// no can do
using no_naivete = no_arrf<arf>;
(MSVC) error C2972: 'no_arrf':
template parameter 'unnamed-parameter':
the type of non-type argument is invalid
I might think this whole story might look like trivial or even useless to some. But, I am sure many good folks are coming to SO for badly needed standard C++ advice. For them, this is neither trivial nor useless.
Many thanks for reading.

Using two namespaces only works partly

When I try to compile this code:
#include <iostream>
namespace Direction
{
enum Enum { UP, DOWN, LEFT, RIGHT };
}
using namespace std;
void move(int pDir);
int main()
{
printf("UP: %u\n", Direction::UP);
printf("DOWN: %u\n", Direction::DOWN);
printf("LEFT: %u\n", Direction::LEFT);
printf("RIGHT: %u\n", Direction::RIGHT);
move(Direction::UP);
return 0;
}
void move(int pDir)
{
printf("Move: ");
switch(pDir)
{
case(Direction::UP):
printf("UP");
break;
case(Direction::DOWN):
printf("DOWN");
break;
case(Direction::RIGHT):
printf("RIGHT");
break;
case(Direction::LEFT):
printf("LEFT");
break;
default:
printf("nothing");
break;
}
}
The result I expect would be:
UP: 0
DOWN: 1
LEFT: 2
RIGHT: 3
Move: UP
Instead the result is:
UP: 0
DOWN: 1
LEFT: 2
RIGHT: 3
It seems like void move(..) just gets ignored.
I already found the problem: It's the using namespace std. When I delete it, I get the result as expected.
So I have three questions:
1) Why does void move(..) just gets "ignored"
2) Why can I access the members of Direction within the first four lines of int main()
3) How can I fix this? ,_,
Have a nice day my friends.
ps: This is an extracted example of my problem, on my project I need to use the namespace std.
Your move function application has been reviewed and unfortunately, a
better application has been found. Please don't hesitate to reach us
for comments or questions.
std::move in utility header is the function being called in this situation. This is due to multiple factors :
The utility header is included by iostream, so it is defined in your code
Because of using namespace std, any function definition in the std namespace is now candidate for overload resolution in the global scope (see Namespace scope).
The argument Direction::UP is a rvalue, and the signature of std::move is template< class T >constexpr typename std::remove_reference<T>::type&& move( T&& t ) noexcept;. T can resolve to the enum type without conversion.
Yours is void move(int pDir); and will require an implicit conversion from Direction::Enum&& to int
When you remove on of these condition your function will be called. For instance
move((int)Direction::UP);
remove the need for an implicit conversion.
Due to your using namespace std both move (yours) and std::move are now accessible through the name move and when you call it, the usual overload resolution takes place, so the compiler checks whether
move(int)
or
template<typename T> move(T) // bit simplified here
is a better match for your call move(Direction::UP). Since the underlying type (aka std::underlying_type) of an unscoped enum is implementation defined, it may be a char or short (or anything else), in which case the second candidate is a better match.
Other factors (like the rvalue-ness mentioned by UmNyobe) and the namespace of the arguments can as well have an influence on overload resolution. Moving the definition of your move into the Direction namespace for example should lead to the first candidate being called, since ADL (argument dependent lookup) kicks in, although I am not 100% sure on that right now.
So my advice, as already suggested by the others, is to avoid using namespace as much as possible, at least at file scope. If you need to access a lot of stuff from one namespace, simply put the using namespace into the function that requires it. Regarding namespace std in particular, I highly recommend to never use using namespace std.

Make first template argument optional

I have a function that does a base 64 encode using Boost. It takes two template parameters: One for the type of container used for input, and one for the type of container used for output. This allows you to do things like provide binary data using a std::vector but get a std::string back.
Here's the code:
template<typename OutputContainer, typename InputContainer>
OutputContainer Encode(InputContainer const& data)
{
using namespace boost::archive::iterators;
using base64_it = base64_from_binary<transform_width<
typename InputContainer::const_iterator, 6, 8>>;
OutputContainer result(base64_it(data.begin()), base64_it(data.end()));
static std::string const padding[] { "", "==", "="};
auto const& pad = padding[data.size() % 3];
result.insert(result.end(), pad.begin(), pad.end());
return result;
}
Usage example:
std::string data = "Hello World!+";
auto encoded = Encode<std::string>(data);
Live sample here
Note in the example above, I still had to provide the template argument for the output container even though it's the same type as the input container. In these scenarios, I'd like the OutputContainer template parameter to be optional and instead use the type deduced by InputContainer. I am not sure what workarounds or adjustments I can perform to get this kind of interface, but it would be nice to see what SO community can come up with.
Note I am also open to a more iterator-centric approach, but I avoided it due to redundancy/boilerplate (I think it's simpler to pass in containers than iterators). If it ends up looking like the 4-argument version of std::transform() I think I'll be a lot less satisfied with the solution.
Using an overload (not a specialization) for the case where InputContainer and OutputContainer is the same, enable_if to disable the original implementation in this case, it's possible to achieve what you're asking for. A caveat is that it will no longer be possible to explicitly specify both container types if they are the same, unless a third argument is also provided:
template<typename OutputContainer, typename InputContainer, typename = std::enable_if_t<!std::is_same_v<OuptputContainer, InputContainer>>>
OutputContainer Encode(InputContainer const& data)
{
// Your implementation
}
template<typename OutputContainer>
OutputContainer Encode(OutputContainer const& data)
{
return Encode<OutputContainer, OutputContainer, void>(data);
}
Example on Godbolt.

How to use the auto and decltype keywords to ease template argument deduction?

I am implementing the Merge sort algorithm. The problem is when I try to use a vector of automatically deduced types within the algorithm.
template <typename TIterator, typename TCompare>
void mergeSort(TIterator begin, TIterator end, TCompare criterium)
{
//...
auto help = *begin; // help is a value (not a reference)
QVector<decltype(help)> leftPart; // now decltype(help) is also a value
//... // and not a reference
}
This works.
But once I make the algorithm pass the TIterators by constant reference, I get an error which I never got in my whole life:
template <typename TIterator, typename TCompare>
void mergeSort(const TIterator& begin, const TIterator& end, TCompare criterium)
{
//...
auto help = *begin; // help is a value (not a reference)
QVector<decltype(help)> leftPart; // now decltype(help) is also a value
//...
}
results in:
In function 'void mergeSort(const TIterator&, const TIterator&, TCompare)':
internal compiler error: in type_unification_real, at cp/pt.c:14176
I am using g++ 4.6.3 on Ubuntu
What went wrong?
An internal compiler error occurs whenever the compiler fails, which means that you found a bug. This is the reason while early adoption of new standards is usually called the bleeding edge: sometimes, it makes you bleed ;)
There might be something wrong with your code, or there might not. It's not possible to tell from this output alone. What is certain is that the compiler does not support it so you might want to change it instead.
In particular, lookup std::iterator_traits<> to see all the things you can deduce from an iterator's type:
typename std::iterator_traits<TIterator>::value_type help = *begin;
// ::reference
// ::pointer
// ...
By circumventing the automatic deduction, you will probably be able to get past the compiler bug.
Note: if you wish to report the bug, which is certainly laudable, you will be asked to produce a preprocessed file reproducing the issue. This file should be as small as possible. It can be generated using -E on the gcc command line and generally ends up with the .ii extension.

How to check if a function exists in C/C++?

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