Passing pointer to template-function, when the template used as argument - c++

While trying to play around with function pointers, I wondered if there's a way to pass as an argument a template-function pointer, which uses an instance of the template as one of its arguments. For example, I have the following template function:
template<class T>
bool match(int i, const T& M){
return i%M.val==0;
}
which will eventually take the following class as T:
class Num{
public:
int val;
Num(int n): val(n) {}
};
(It's just a training code, I'm not using it for something of course)
Now, I have the following function, which is basically an implementation of count_if:
int countMod(const vector<int>& v, int mod, **???**){
Num nMod(mod);
int cnt=0;
for(vector<int>::const_iterator it=v.begin(); it!=v.end();it++){
if(match(*it, nMod)){
cnt++;
}
}
return cnt;
}
The method is supposed to return the number of elements divisible by mod.
The third argument is the one I'm not sure about of course.
I want to somehow pass a pointer to the template function match<Num>, with Num(mod) as M .
I understand that it's quite weird to pass a pointer to something that doesn't actually exist, since I haven't instantiated an actual function, say match,
but since the function match is supposed to get const T&, I'm really not sure how to sort it out, if possible.
Edit:
I repaired the call to match as mentioned in the first comment, and yet I'm not sure what to pass as argument to countMod. I guess its something like bool(*match)(int, **???**), but I don't know for certain.

The simpler would be templatize your method
template <typename F>
int countMod(const vector<int>& v, int mod, F f)
{
Num nMod(mod);
int cnt = 0;
for(vector<int>::const_iterator it=v.begin(); it!=v.end();it++){
if(f(*it, nMod)){
cnt++;
}
}
return cnt;
}
A more descriptive way would be
int countMod(const vector<int>& v, int mod, std::function<bool (int, Num)> f)
{
Num nMod(mod);
int cnt = 0;
for(vector<int>::const_iterator it=v.begin(); it!=v.end();it++){
if(f(*it, nMod)){
cnt++;
}
}
return cnt;
}
and call it in both case
countMod(v, mod, &match<Num>);

As you noted in the comment to Jarod42's answer, there's no real reason to pass in mod, because the only thing you do with mod is to feed it back to the function that's also getting passed in. So a logical thing to do is just to restructure your code:
template <typename F>
int count(const vector<int>& v, F f)
{
int cnt = 0;
for(vector<int>::const_iterator it=v.begin(); it!=v.end();it++){
if(f(*it)){
cnt++;
}
}
return cnt;
}
Now, you can just do the following:
int mod = 3; // or whatever
auto c = count(v, [nmod = Num(mod)] (int x) { return match(x, nmod); });
Note that this requires C++14, but you can easily modify it to work with 11. What we're doing now, is instead of passing the function directly, we use a lambda to bind one of the arguments before passing it in. This sort of thing is common when working with higher order functions.
Of course, you might notice at this point that count is looking really generic. It's really only non-generic in the container argument, insofar as it requires specifically a vector of integers. If we make that part generic too, we end up with a function in the standard library: count_if. Your problem can also be solved as:
auto c = std::count_if(v.begin(), v.end(),
[nmod = Num(mod)] (int x) { return match(x, nmod); });

Related

C++ use function's output as functions input n times

I'm sorry for the weird title. I don't know how to word this.
If I have function func()
How do I do this:
func(func(func(func(func(x)))))
where it repeats N times?
I'm trying to implement Conway's Game of Life. I have a function that takes a vector and outputs another vector, which is the next generation of the input vector. So generation 3's vector would be func(func(func(x))).
The easy way, simply using for loop:
int x = some_initial_value;
for (int i = 0; i < NUMBER_OF_ITERATIONS; ++i)
{
x = func(x);
}
While the 'easy way' works in most cases, I'd like to provide you a way to do in in cases where return type (for a given argument type) might differ from argument type:
template<size_t i, typename F, typename Arg>
auto times(F f, const Arg& arg) {
if constexpr (i == 0) {
return arg;
} else {
return times<i - 1>(f, f(arg));
}
}
// usage: times<5>(func, x);

What is the difference between different ways of passing a function as an argument to another function?

I have the situation where one function calls one of several possible functions. This seems like a good place to pass a function as a parameter. In this Quoara answer by Zubkov there are three ways to do this.
int g(int x(int)) { return x(1); }
int g(int (*x)(int)) { return x(1); }
int g(int (&x)(int)) { return x(1); }
...
int f(int n) { return n*2; }
g(f); // all three g's above work the same
When should which method be used? What are there differences? I prefer the simplest approach so why shouldn't the first way always be used?
For my situation, the function is only called once and I'd like to keep it simple. I have it working with pass by pointer and I just call it with g(myFunc) where myFunc is the function that gets called last.
Expanding on L.F.'s comment, it's often better to eschew function pointers entirely, and work in terms of invocable objects (things which define operator()). All of the following allow you to do that:
#include <type_traits>
// (1) unrestricted template parameter, like <algorithm> uses
template<typename Func>
int g(Func x) { return x(1); }
// (2) restricted template parameter to produce possibly better errors
template<
typename Func,
typename=std::enable_if_t<std::is_invocable_r_v<int, Func, int>>
>
int g(Func x) { return std::invoke(x, 1); }
// (3) template-less, trading a reduction in code size for runtime overhead and heap use
int g(std::function<int(int)> x) { return x(1); }
Importantly, all of these can be used on lambda functions with captures, unlike any of your options:
int y = 2;
int ret = g([y](int v) {
return y + v;
});

C++ Math Parser with user-defined function

I want to implement a math parser with user-defined function.
There are several problems to be solved.
For example, int eg(int a,int b){return a+b;} is the function I want to add to the parser.
First: How to store all the functions into a container?
std::map<std::string,boost::any> func_map may be a choose (by func_map["eg"]=eg". However, It's very hard to call the function in this kind of map, for I have to use any_cast<T> to get the real function from the wrapper of boost::any.
Second: How to handle the overloaded function?
It's true that I can distinguish the overloaded functions by the method of typeid, but it's far from a real implementation.
Parsering expressions is not a difficult skill and the hardest part is described above.
muparserx provides an interesting solution for this problem, but I'm finding another method.
I'm not familiar with lambda expressions but may be it's an acceptable way.
Update:
I need something like this:
int eg(int a,int b){ return a+b;}
int eg(int a,int b, string c){return a+b+c.length();}
double eh(string a){return length.size()/double(2);}
int main(){
multimap<string,PACKED_FUNC> func_map;
func_map.insert(make_pair("eg",pack_function<int,int>(eg));
func_map.insert(make_pair("eg",pack_function<int,int,string>(eg));
func_map.insert(make_pair("eh",pack_function<string>(eh));
auto p1=make_tuple(1,2);
int result1=apply("eg",PACK_TUPLE(p1));//result1=3
auto p2=tuple_cat(p1,make_tuple("test"));
int result2=apply("eg",PACK_TUPLE(p2));//result2=7
auto p3=make_tuple("testagain");
double result3=apply("eh",PACK_TUPLE(p3));//result3=4.5
return 0;
}
How to store all the functions into a container?
To store then inside some container, they must be of the same type. The std::function wrapper is a good choice, since this allows you to use even stateful function objects. Since you probably don't want all functions to take the same number of arguments, you need to "extract" the arity of the functions from the static host type system. An easy solution is to use functions that accept a std::vector:
// Arguments type to the function "interface"
using Arguments = std::vector<int> const &;
// the interface
using Function = std::function<int (Arguments)>;
But you don't want your users to write functions that have to unpack their arguments manually, so it's sensible to automate that.
// Base case of packing a function.
// If it's taking a vector and no more
// arguments, then there's nothing left to
// pack.
template<
std::size_t N,
typename Fn>
Function pack(Fn && fn) {
return
[fn = std::forward<decltype(fn)>(fn)]
(Arguments arguments)
{
if (N != arguments.size()) {
throw
std::string{"wrong number of arguments, expected "} +
std::to_string(N) +
std::string{" but got "} +
std::to_string(arguments.size());
}
return fn(arguments);
};
}
The above code handles the easy case: A function that already accepts a vector. For all other functions they need to be wrapped and packed into a newly created function. Doing this one argument a time makes this relatively easy:
// pack a function to a function that takes
// it's arguments from a vector, one argument after
// the other.
template<
std::size_t N,
typename Arg,
typename... Args,
typename Fn>
Function pack(Fn && fn) {
return pack<N+1, Args...>(
[fn = std::forward<decltype(fn)>(fn)]
(Arguments arguments, Args const &... args)
{
return fn(
arguments,
arguments[N],
args...);
});
}
The above only works with (special) functions that already take a vector. For normal functions we need an function to turn them into such special functions:
// transform a function into one that takes its
// arguments from a vector
template<
typename... Args,
typename Fn>
Function pack_function(Fn && fn) {
return pack<0, Args...>(
[fn = std::forward<decltype(fn)>(fn)]
(Arguments arguments, Args const &... args)
{
return fn(args...);
});
}
Using this, you can pack any function up to be the same type:
Function fn =
pack_function<int, int>([] (auto lhs, auto rhs) {return lhs - rhs;});
You can then have them in a map, and call them using some vector, parsed from some input:
int main(int, char**) {
std::map<std::string, Function> operations;
operations ["add"] = pack_function<int, int>(add);
operations ["sub"] = pack_function<int, int>(
[](auto lhs, auto rhs) { return lhs - rhs;});
operations ["sum"] = [] (auto summands) {
int result = 0;
for (auto e : summands) {
result += e;
}
return result;
};
std::string line;
while (std::getline(std::cin, line)) {
std::istringstream command{line};
std::string operation;
command >> operation;
std::vector<int> arguments {
std::istream_iterator<int>{command},
std::istream_iterator<int>{} };
auto function = operations.find(operation);
if (function != operations.end ()) {
std::cout << line << " = ";
try {
std::cout << function->second(arguments);
} catch (std::string const & error) {
std::cout << error;
}
std::cout << std::endl;
}
}
return 0;
}
A live demo of the above code is here.
How to handle the overloaded function? It's true that I can distinguish the overloaded functions by the method of typeid, but it's far from a real implementation.
As you see, you don't need to, if you pack the relevant information into the function. Btw, typeid shouldn't be used for anything but diagnostics, as it's not guaranteed to return different strings with different types.
Now, finally, to handle functions that don't only take a different number of arguments, but also differ in the types of their arguments, you need to unify those types into a single one. That's normally called a "sum type", and very easy to achieve in languages like Haskell:
data Sum = IVal Int | SVal String
-- A value of type Sum is either an Int or a String
In C++ this is a lot harder to achieve, but a simple sketch could look such:
struct Base {
virtual ~Base() = 0;
};
inline Base::~Base() {}
template<typename Target>
struct Storage : public Base {
Target value;
};
struct Any {
std::unique_ptr<Base const> value;
template<typename Target>
Target const & as(void) const {
return
dynamic_cast<Storage<Target> const &>(*value).value;
}
};
template<typename Target>
auto make_any(Target && value) {
return Any{std::make_unique<Storage<Target>>(value)};
}
But this is only a rough sketch, since there's boost::any which should work perfectly for this case. Note that the above and also boost::any are not quite like a real sum type (they can be any type, not just one from a given selection), but that shouldn't matter in your case.
I hope this gets you started :)
Since you had problems adding multi type support I expanded a bit on the above sketch and got it working. The code is far from being production ready, though: I'm throwing strings around and don't talk to me about perfect forwarding :D
The main change to the above Any class is the use of a shared pointer instead of a unique one. This is only because it saved me from writing copy and move constructors and assignment operators.
Apart from that I added a member function to be able to print an Any value to a stream and added the respective operator:
struct Base {
virtual ~Base() = 0;
virtual void print_to(std::ostream &) const = 0;
};
inline Base::~Base() {}
template<typename Target>
struct Storage : public Base {
Target value;
Storage (Target t) // screw perfect forwarding :D
: value(std::forward<Target>(t)) {}
void print_to(std::ostream & stream) const {
stream << value;
}
};
struct Any {
std::shared_ptr<Base const> value;
template<typename Target>
Target const & as(void) const {
return
dynamic_cast<Storage<Target> const &>(*value).value;
}
template<typename T>
operator T const &(void) const {
return as<T>();
}
friend std::ostream & operator<<(std::ostream& stream, Any const & thing) {
thing.value->print_to(stream);
return stream;
}
};
template<typename Target>
Any make_any(Target && value) {
return Any{std::make_shared<Storage<typename std::remove_reference<Target>::type> const>(std::forward<Target>(value))};
}
I also wrote a small "parsing" function which shows how to turn a raw literal into an Any value containing (in this case) either an integer, a double or a string value:
Any parse_literal(std::string const & literal) {
try {
std::size_t next;
auto integer = std::stoi(literal, & next);
if (next == literal.size()) {
return make_any (integer);
}
auto floating = std::stod(literal, & next);
if (next == literal. size()) {
return make_any (floating);
}
} catch (std::invalid_argument const &) {}
// not very sensible, string literals should better be
// enclosed in some form of quotes, but that's the
// job of the parser
return make_any<std:: string> (std::string{literal});
}
std::istream & operator>>(std::istream & stream, Any & thing) {
std::string raw;
if (stream >> raw) {
thing = parse_literal (raw);
}
return stream;
}
By also providing operator>> it's possible to keep using istream_iterators for input.
The packing functions (or more precisely the functions returned by them) are also modified: When passing an element from the arguments vector to the next function, an conversion from Any to the respective argument type is performed. This may also fail, in which case a std::bad_cast is caught and an informative message rethrown. The innermost function (the lambda created inside pack_function) wraps its result into an make_any call.
add 5 4 = 9
sub 3 2 = 1
add 1 2 3 = wrong number of arguments, expected 2 but got 3
add 4 = wrong number of arguments, expected 2 but got 1
sum 1 2 3 4 = 10
sum = 0
sub 3 1.5 = argument 1 has wrong type
addf 3 3.4 = argument 0 has wrong type
addf 3.0 3.4 = 6.4
hi Pete = Hello Pete, how are you?
An example similar to the previous one can be found here. I need to add that this Any type doesn't support implicit type conversions, so when you have an Any with an int stored, you cannot pass that to an function expecting a double. Though this can be implemented (by manually providing a lot of conversion rules).
But I also saw your update, so I took that code and applied the necessary modifications to run with my presented solution:
Any apply (multimap<string, Function> const & map, string const & name, Arguments arguments) {
auto range = map.equal_range(name);
for (auto function = range.first;
function != range.second;
++function) {
try {
return (function->second)(arguments);
} catch (string const &) {}
}
throw string {" no such function "};
}
int eg(int a,int b){ return a+b;}
int eg(int a,int b, string c){return a+b+c.length();}
double eh(string a){return a.size()/double(2);}
int main(){
multimap<string, Function> func_map;
func_map.insert(make_pair(
"eg",pack_function<int,int>(
static_cast<int(*)(int, int)>(&eg))));
func_map.insert(make_pair(
"eg",pack_function<int,int,string>(
static_cast<int (*)(int, int, string)>(&eg))));
func_map.insert(make_pair(
"eh",pack_function<string>(eh)));
// auto p1=make_tuple(1,2);
// if you want tuples, just write a
// function to covert them to a vector
// of Any.
Arguments p1 =
{make_any (1), make_any (2)};
int result1 =
apply(func_map, "eg", p1).as<int>();
vector<Any> p2{p1};
p2.push_back(make_any<string> ("test"));
int result2 =
apply(func_map, "eg", p2).as<int>();
Arguments p3 = {make_any<string>("testagain")};
double result3 =
apply(func_map, "eh", p3).as<double>();
cout << result1 << endl;
cout << result2 << endl;
cout << result3 << endl;
return 0;
}
It doesn't use tuples, but you could write a (template recursive) function to access each element of a tuple, wrap it into an Any and pack it inside a vector.
Also I'm not sure why the implicit conversion from Any doesn't work when initialising the result variables.
Hm, converting it to use boost::any shouldn't be that difficult. First, the make_any would just use boost::any's constructor:
template<typename T>
boost::any make_any(T&& value) {
return boost::any{std::forward<T>(value)};
}
In the pack function, the only thing that I'd guess needs to be changed is the "extraction" of the correct type from the current element in the arguments vector. Currently this is as simple as arguments.at(N), relying on implicit conversion to the required type. Since boost::any doesn't support implicit conversion, you need to use boost::any_cast to get to the underlying value:
template<
std::size_t N,
typename Arg,
typename... Args,
typename Fn>
Function pack(Fn && fn) {
return pack<N+1, Args...>(
[fn = std::forward<decltype(fn)>(fn)]
(Arguments arguments, Args const &... args)
{
try {
return fn(
arguments,
boost::any_cast<Arg>(arguments.at(N)),
args...);
} catch (boost::bad_any_cast const &) { // throws different type of exception
throw std::string{"argument "} + std::to_string (N) +
std::string{" has wrong type "};
}
});
}
And of course, if you use it like in the example you provided you also need to use boost::any_cast to access the result value.
This should (in theory) do it, eventually you need to add some std::remove_reference "magic" to the template parameter of the boost::any_cast calls, but I doubt that this is neccessary.
(typename std::remove_reference<T>::type instead of just T)
Though I currently cannot test any of the above.

what kind of language feature is suitable for similar functions with only several different lines?

I have a programming problem and I thought it for several days, but still without good solutions.
There are several big, long and similar functions, in which only several lines are different. For example:
void bigfunc(){
//blabla..
double i, j, k;
double result;
//only this part is different
{ result=i++; } //in bigfunc1;
{ result=i*cos(j);} //in bigfunc2;
{ result=sin(i)*cos(j)*tan(k);} //in bigfunc3;
//blabla...
}
The simplest way is copying the bigfunc 3 times and edit the different lines respectively. Obviously, it is not a good idea.
Now, I choose the template function method in c++, which embraces the different lines into several small functions, such as:
< template class F >
void bigfunc(F& f){
...
f(i,j,k); //call the function.
...
}
void f1(int i, int j, int k){
i++; //only use parameter i!
}
void f2(int i, int j, int k){
i++; j++; //only use parameter i and j!
}
void f3(int i, int j, int k){
i++; j++; j++;
}
However, we have to unify the prototype of f(int, int, int) to include all input parameters in three different bigfuncs, while in fact, in bigfunc1 for example, only f(int i) is needed indeed. Therefore, this method seems not elegant enough.
I though that if there are some abstract mechanics which can take a sentence block as a function parameter or as a template function parameter. That will be amazing! For example (pseudocode):
< template class Code>
void bigfunc(Code code){
//...
code(); //direct expand the code in place, which will be amazingly beautiful.
//....
}
code1(){
i++; //just be care for the variable name, like #include
}
....
Are there some other compiler-time abstract mechanics in any language, which can solve such problem elegantly.
By now, I only heard that the D language's static_if perhaps could tackle such situation. For example:
< template class F>
void bigfunc(F f){
if( static_if(f) == func1 ) //it is justified at compile-time, not at run-time.
i++;
else if ( static_if(f)==func2){
i++; j++;
}...
}
sorry for that I don't know D, and it is just for explanation.
Thanks for any suggestion!
You could do it a few different ways in D. One would be:
void bigfunc(string code)(){
//blabla..
double i, j, k;
double result;
//only this part is different
mixin(code);
//blabla...
}
alias bigfunc!"{ result=i++; }" bigfunc1;
alias bigfunc!"{ result=i*cos(j); }" bigfunc2;
alias bigfunc!"{ result=sin(i)*cos(j)*tan(k);}" bigfunc3;
This is similar to the C macro way - you pass a string to the template (the first set of arguments are compile-time template args, the second set are regular function arguments) which is then mixed in as code to create the function.
You could also do it with static if easily enough.
void bigfunc(int version)(){
//blabla..
double i, j, k;
double result;
static if(version == 1)
{ result=i++; }
else static if(version == 2)
// well you get the idea
Then you can alias different template arguments to new names just like with the string.
You could use just a macro:
#define CREATE_FUNC(name, code) \
void name(){ \
//blabla.. \
int i, j, k; \
\
//only this part is different \
code \
\
//blabla... \
}
CREATE_FUNC(bigfunc1, { i++; });
CREATE_FUNC(bigfunc2, { i++; j++; });
CREATE_FUNC(bigfunc3, { i++; j++; k++; });
Not so beautiful and "c-plus-plussy", however.
The mythical programming language feature you are looking for is called "subroutine":
void bigfunc(int variant){
//blabla..
double i, j, k;
double result;
//only this part is different
switch (variant) {
case 0: { result=i++; } break; //in bigfunc1;
case 1: { result=i*cos(j);} break; //in bigfunc2;
case 2: { result=sin(i)*cos(j)*tan(k);} break; //in bigfunc3;
}
//blabla...
}
void bigfuncA() { bigfunc(0); }
void bigfuncB() { bigfunc(1); }
void bigfuncC() { bigfunc(2); }
Not quite sure this is what you're after, but function objects may do the trick.
template<typename Func, typename... Args>
void bigfunc(Func f, Args... args) {
//blahblah
f(args...);
//blahblah
}
struct f1 {
void operator()(int& i) {
++i;
}
};
struct f2 {
void operator()(int& i, int& j) {
f1()(i);
++j;
}
};
struct f3 {
void operator()(int& i, int& j, int& k) {
f2()(i, j);
++k;
}
};
//main...
int i, j, k;
//...
bigfunc(f3(), i, j, k);
Why don't you put the 'common code' inside an inline function which will then be called by all three functions?
This is easy enough to solve by writing a single higher order function (HOF), which is a paradigm from functional programming. One common use case is opening a file, doing something with it, then closing it again. The traditional and error-prone way is to do this manually. HOFs provide an elegant alternative:
void *withFile(const char *fp, const char *mode, void *(*k)(FILE *)) {
FILE *fh;
void *result;
fh = fopen(fp, mode);
if (fh == NULL) return NULL;
result = k(fh);
fclose(fh);
return result;
}
Now you can write several small functions that only deal with the actual file reading. The withFile procedure makes sure that the file is always closed. For a more in-depth explanation of this paradigm, you can read my old blog article.
Note that the user function does not care if it is passed extra arguments. Just ignore the extra arguments in the user function.
Your first template approach doesn't look too horrible, and unless profiling proves otherwise chances are that the compiler will optimize away the unneeded functions and unused variables, especially if you don't give them names in the declaration of f1 and f2.
But in order to generalize things you need to take a step back and think about the what you actually want to do in an abstract way and not about how you have done it in the concrete case. What do i,j,k actually mean? You have a set of counter variables, and at one point in your bigfunction you want to increase all of them:
template <int N>
struct Counting_Variables;
template <>
struct Counting_Variables<1> {
int i;
};
template <>
struct Counting_Variables<2> {
int i, j;
};
template <>
struct Counting_Variables<3> {
int i,j,k;
};
void increase_counters ( Counting_Variables<1> & arguments ) {
++(arguments.i);
}
void increase_counters ( Counting_Variables<2> & arguments ) {
++(arguments.i);
++(arguments.j);
}
void increase_counters ( Counting_Variables<3> & arguments ) {
++(arguments.i);
++(arguments.j);
++(arguments.k);
}
void bigfunction () {
// Enter appropriate number of counter variables as template argument here:
Counting_Variables<2> counters;
// Be lazy and introduce shortcuts for counters.i etc.
int & i = counters.i;
int & j = counters.j;
// do some stuff here
// increase all the counters
increase_counters( counters );
// do more stuff here
};
I am guilty as charged, making the Counting_Variables a template is not strictly necessary. Calling them Counting_Variables_with_i_and_j instead of N=2 has the same effect.

sort by using a member of an object in c++

I'd like to use sort() to do the following
I have a text char[] T which is (private) member of a class. The text has length n.
I also ave an array int[] P that contains the first n integers.
I'd like to std::sort P such that the lexicographic order among suffixes of T are preserved
i.e., for any i < j we have that T[P[i]...n] is lex smaller than T[P[j]...n].
I'm able to do it when char[] T is a global variable by defining
bool myfunction (int i,int j) {
int m = i, l = j;
while(m<n and l <n) {
if(T[m] != T[l]) return (T[m]<T[l]);
m++; l++;
}
return (m<l);
}
and calling std::sort(P, P+n, myfuction)
I'm in truble when T is a member of an object (and sort is called by a method of that object).
How can I define myfunction so that T is visible?
Should it be member of that object? If yes, how?
Thank you very much.
Edit: bool instead of int
As you guessed, one way to do it is by defining yourfunction() as a public member of that class.
Example:
#include <algorithm>
#include <vector>
using namespace std;
class T
{
private:
int value;
public:
T()
{
value = rand() % 100;
}
static bool Compare(const T &a, const T &b)
{
return a.value < b.value;
}
};
int main(int argc, char** argv)
{
vector<T> data;
//add some data
for (int i=0; i<10; i++)
data.push_back(T());
//sort using static method that can access private attributes
std::sort(data.begin(), data.end(), T::Compare);
}
If sort represents std::sort, the function that you are using as predicate is wrong for a couple of reasons, the first of which is that the returned type from the function should be a bool and not an int.
The next thing that is wrong is that the predicate is required to be consistent, that is, given two inputs a and b the result of predicate( a, b ) must be either true or false and always the same. If that condition is not met, the result of calling sort will be undefined, possibly including an infinite loop.
The approach (rather than the predicate itself) is probably not good either, as the number of times that the predicate will be called depends on the input data, and the results of the different calls to the predicate (until the algorithm thinks, that according to your partial order, the sequence is sorted).
You probably need a functor object:
struct myfunctor {
const char *T;
size_t n;
myfunctor(const char *T, size_t n) : T(T), n(n) {}
bool operator()(int i, int j) {
// stuff using T and n
}
// Optionally, something along these lines, I haven't tested it
template <size_t N> myfunctor(const char (&x)[N]) : T(&x[0]), n(N) {}
template <size_t N> myfunctor(char (&x)[N]) : T(&x[0]), n(N) {}
};
SomeObjectContainingT x;
std::sort(P, P+n, myfunctor(x.T, x.n));
Or if x.T is an actual array rather than just a pointer, the template constructors will capture the array size from the type, no need for a second parameter:
std::sort(P, P+n, myfunctor(x.T));
Edit: sorry, missed that T is private. I think you have two issues here, scope and accessibility. The functor solves the scope problem, now for the accessibility.
If you want external functions to access T, x must provide a means to access it. For example, it could return the functor object:
class SomeObjectContaining T {
char T[23];
public:
myfunctor comparator() { return myfunctor(T); }
};
std::sort(P, P+n, x.comparator());
Or you could mess about with friend: define your functor class as a friend of SomeObjectContainingT, then pass the object to its constructor rather than the array.