9 Replies - 401 Views - Last Post: 02 April 2013 - 08:33 AM Rate Topic: -----

#1 KryziK  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 27-March 13

Function and Struct Templating

Posted 27 March 2013 - 08:56 PM

I have two functions, FindStringA and FindStringW, like so:

vector<FindStringResultA> FindStringA(char *szPattern) {
    vector<FindStringResultA> vecReturn;

    char *szText = new char[strlen(szPattern) + 1];
    ZeroMemory(szText, strlen(szPattern) + 1);
    memcpy(szText, (void *)szPattern, strlen(szPattern));
    vecReturn.push_back(FindStringResultA(1, szText));

    return vecReturn;
}
vector<FindStringResultW> FindStringW(wchar_t *szPattern) {
    vector<FindStringResultW> vecReturn;

    wchar_t *szText = new wchar_t[wcslen(szPattern) + 1];
    ZeroMemory(szText, wcslen(szPattern) + 1);
    memcpy(szText, (void *)szPattern, wcslen(szPattern));
    vecReturn.push_back(FindStringResultW(2, szText));

    return vecReturn;
}



And the structs, FindStringResultA and FindStringResultW, like so:

struct FindStringResultA {
    int Number;
    char *Text;

    FindStringResultA(int iNumber, char *szText) {
        Number = iNumber;
        Text = szText;
    }

    ~FindStringResultA() {
        delete Text;
    }
};

struct FindStringResultW {
    int Number;
    wchar_t *Text;

    FindStringResultW(int iNumber, wchar_t *szText) {
        Number = iNumber;
        Text = szText;
    }

    ~FindStringResultW() {
        delete Text;
    }
};



The true functions and structs have been replaced for readability and simplicity. Assume there is no function existing for my purpose already included in any libraries.

I've used templates before. However, I can't figure out a way to template both the structs and the functions in such a way that I can use the code like so:

vector<FindStringResult> FoundStringTable = FindString(szPattern);



where the only determining factor of the struct/function is the function's parameter (whether it's a char* or wchar_t*).
Is this possible? If not, what's the closest I can get to this? I was hoping not to use something like:

vector<FindStringResult<char>> FoundStringTable = FindString(szPattern);



simply because that's a little more work (and it's uglier) than two structs ending with either an A or W.

Also, the two functions will be identical besides the differences between operations on char* and wchar_t, meaning the only differences will be strlen vs wcslen, strcpy vs wcscpy, and similar functions.

Please let me know if I need to provide any more information.

Thanks!

Is This A Good Question/Topic? 0
  • +

Replies To: Function and Struct Templating

#2 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1311
  • View blog
  • Posts: 4,505
  • Joined: 19-February 09

Re: Function and Struct Templating

Posted 27 March 2013 - 11:48 PM

Perhaps something like,

TCHAR expands to wchar_t or char depending on whether the code is compiled as Unicode or not, so you might not need both structs.

_tcslen expands as well.


Working with Strings
Was This Post Helpful? 0
  • +
  • -

#3 KryziK  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 27-March 13

Re: Function and Struct Templating

Posted 28 March 2013 - 08:21 AM

View Post#define, on 27 March 2013 - 11:48 PM, said:

Perhaps something like,

TCHAR expands to wchar_t or char depending on whether the code is compiled as Unicode or not, so you might not need both structs.

_tcslen expands as well.


Working with Strings


I need both to work as I need to operate with both types of strings during runtime.
Was This Post Helpful? 0
  • +
  • -

#4 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1311
  • View blog
  • Posts: 4,505
  • Joined: 19-February 09

Re: Function and Struct Templating

Posted 28 March 2013 - 09:01 AM

Hi, how about using one struct and using the constructor to differentiate between the strings?

#include <iostream>
#include <windows.h>

using namespace std;

struct FindString {
    int number;
    wchar_t *wText;
    char    *cText;

    FindString(char * Text) 
        {cout << "narrow" << endl;}
    FindString(wchar_t * Text) 
        {cout << "wide" << endl;}
};


int main()
{
  FindString narrow("hello");
  FindString wide(L"hello");

  return 0;
}




You could have a boolean to tell if it is a wide string, or use nulls on the pointers.

.

This post has been edited by #define: 28 March 2013 - 09:01 AM

Was This Post Helpful? 1
  • +
  • -

#5 KryziK  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 27-March 13

Re: Function and Struct Templating

Posted 28 March 2013 - 09:27 AM

View Post#define, on 28 March 2013 - 09:01 AM, said:

Hi, how about using one struct and using the constructor to differentiate between the strings?

#include <iostream>
#include <windows.h>

using namespace std;

struct FindString {
    int number;
    wchar_t *wText;
    char    *cText;

    FindString(char * Text) 
        {cout << "narrow" << endl;}
    FindString(wchar_t * Text) 
        {cout << "wide" << endl;}
};


int main()
{
  FindString narrow("hello");
  FindString wide(L"hello");

  return 0;
}




You could have a boolean to tell if it is a wide string, or use nulls on the pointers.

.


I suppose this would work, however I would just have to differentiate between the two types of strings:

vector<FindStringResult> FoundStringTable = FindString(szPattern);
FoundStringTable[0].cText; //FoundStringTable[0].wText;


Out of the two solutions, which one would use less memory? Two separate structs, or one struct with an additional variable. Or is it hard to say?
Was This Post Helpful? 0
  • +
  • -

#6 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,595
  • Joined: 16-October 07

Re: Function and Struct Templating

Posted 28 March 2013 - 09:53 AM

It looks like you're killing yourself for no real reason here. Just use wstring for everything and call it a day. You can convert it to string or char * if you need.
Was This Post Helpful? 1
  • +
  • -

#7 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1311
  • View blog
  • Posts: 4,505
  • Joined: 19-February 09

Re: Function and Struct Templating

Posted 28 March 2013 - 10:44 AM

View Postbaavgai, on 28 March 2013 - 04:53 PM, said:

Just use wstring for everything and call it a day. You can convert it to string or char * if you need.


Just getting around to thinking that.


View PostKryziK, on 28 March 2013 - 04:27 PM, said:

Out of the two solutions, which one would use less memory? Two separate structs, or one struct with an additional variable. Or is it hard to say?


Probably two structs, but it is usually better thinking about providing functionality initially, rather than effiency.
Was This Post Helpful? 0
  • +
  • -

#8 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,595
  • Joined: 16-October 07

Re: Function and Struct Templating

Posted 28 March 2013 - 11:56 AM

Just for fun. And to provide inate conversion functionality:
#include <iostream>
#include <sstream>

using namespace std;

struct GenString {
	GenString(const string &);
	GenString(const wstring &);
	
	std::string str() const;
	std::wstring wstr() const;
private:
	std::wstring data;
};

std::ostream &operator<<(std::ostream &out, const GenString &s) { out << s.str(); return out; }

int main() {
	GenString gsFoo("foo");
	GenString gsBar(L"bar");
	
	cout << gsFoo << endl;
	cout << gsBar << endl;

	return 0;
}

GenString::GenString(const string &s) {
	std::wostringstream ss;
	const ctype<wchar_t>& f = use_facet< ctype<wchar_t> >( ss.getloc() ) ;
	for(std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
		ss << f.widen( *it ) ;
	}
	data = ss.str();
}

GenString::GenString(const wstring &s) : data(s) { }

std::string GenString::str() const { 
	std::ostringstream ss;
	const ctype<char>& f = use_facet< ctype<char> >( ss.getloc() ) ;
	for(std::wstring::const_iterator it = data.begin(); it != data.end(); ++it) {
		ss << f.narrow( *it, 0 ) ;
	}
	return ss.str();

}

std::wstring GenString::wstr() const { return data; }



Now you can move from one type to another without worrying about it too much.
Was This Post Helpful? 0
  • +
  • -

#9 KryziK  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 27-March 13

Re: Function and Struct Templating

Posted 28 March 2013 - 01:17 PM

Thank you all for the replies. I think I'll stick with either what I'm doing or use #define's idea of having both pointers inside of the struct. Is there a way to mark my question as adequately solved?
Was This Post Helpful? 0
  • +
  • -

#10 KryziK  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 27-March 13

Re: Function and Struct Templating

Posted 02 April 2013 - 08:33 AM

View PostKryziK, on 28 March 2013 - 01:17 PM, said:

Thank you all for the replies. I think I'll stick with either what I'm doing or use #define's idea of having both pointers inside of the struct. Is there a way to mark my question as adequately solved?


Actually, I have an additional question. Because the struct is created in the function (and added to the vector there), the destructor gets called when leaving the function. How can I make sure that Text is still a valid char * but still clean up correctly before exiting the program?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1