1

I know I can do namespace FILE { using boost::filesystem::rename }; which I will do if there's no other solution, but wondering if I can get it inside the class so I can be DRY. I want to create a class called FILE and have no need for namespace FILE.

// class-qualified name is required
using boost::filesystem::rename

// definition not found
void(*rename)(const path&, const path&) = boost::filesystem::rename;

// cannot determine which overloaded instance
function rename = std::mem_fn<void(const path&, const path&)>(boost::filesystem::rename);

// not an alias, creates a new function
function<void(const path&, const path&)> rename = [](const path& old_p, const path& new_p) { boost::filesystem::rename(old_p, new_p); };

// all sorts of errors
auto rename = std::mem_fn(static_cast<void()(const path&, const path&)>(&boost::filesystem::rename));

// nope!
void constexpr rename = boost::filesystem::rename

I am trying to do this:

class FILE {
public:
    // Would like to alias boost::filesystem::rename as rename here
};

What is the correct syntax?

Elan Hickler
  • 1,099
  • 1
  • 11
  • 28
  • if `rename` is the alias of `boost::filesystem` shouldnt `using rename = boost::filesystem` do the trick ? – KostasRim Dec 01 '15 at 19:23
  • @KostasRim, It's an alias of the function, not the namespace, and an overloaded function at that. – chris Dec 01 '15 at 19:27
  • Your third example works for me if I add in the appropriate qualification on `path`, which is not in the global namespace. Unfortunately, I don't think you're going to do much better than that since functions, especially overloaded functions, do not play as nicely in C++ as they do in other languages. This would be easier if `boost::filesystem::rename` were a function object rather than a function. – chris Dec 01 '15 at 19:28
  • @KostasRim I didn't know about this syntax, thanks! It doesn't solve my problem, but still helpful. – Elan Hickler Dec 01 '15 at 19:29
  • What problem are you trying to solve (what interface/call method are you trying to create)? You can't make it a non-static class method because the boost method doesn't take an object of your class type. And I don't think there's a way to "use" a free function as a static function in your class short of writing the one-line delegator. – Mark B Dec 01 '15 at 19:30
  • @ElanHickler the general syntrax for type alias is `using name_alias = TYPE` where name_alias is your prefered name and TYPE is whatever type you are using. Anyway glad i i helped :) – KostasRim Dec 01 '15 at 19:31
  • @chris i did not know about boost so i couldnt tell. – KostasRim Dec 01 '15 at 19:31
  • It's a bad idea to call your class `FILE` if you plan to include `boost/filesystem`... – Toby Speight Dec 01 '15 at 19:33
  • Could I solve this problem by making file a sub-namespace? For example if my project is called SALT, I could do `namespace SALT { class FILE ...` – Elan Hickler Dec 01 '15 at 19:38
  • Try something like http://ideone.com/I4wlY8 – n. m. could be an AI Dec 01 '15 at 19:40
  • somewhat related, adding the link for myself: http://stackoverflow.com/questions/2543205/define-a-struct-inside-a-class-in-c and http://stackoverflow.com/questions/13484387/why-cant-we-declare-a-namespace-within-a-class – Elan Hickler Dec 01 '15 at 23:24

2 Answers2

1

If I understand correctly you want to have a pseudo method in a class that is not actually a method, but some sort of an alias for another function.

As far as I know, that cannot be done in C++. You need to have an actual method or a function object data member that is just a thin layer to your desired function.

A method adds almost no overhead (not a data member so definitely no space overhead, and contains just a call, so it can trivially inlined). And since the method carries no state of the object, you should make it static:

class A {
  static void rename(const path& old_p, const path& new_p) {
      boost:fs::rename(old_p, new_p);
  }
  void rename(const path& old_p, const path& new_p, system::error_code& ec) {
     boost::fs::rename(old_p, new_p, ec);
  }
};

or:

class A {
  template <class... Args>
  static void rename(Args... args) {
     boost::fs::rename(args...); // depending on function and arguments
                                 // you might want to `std::forward`
  }
};
bolov
  • 72,283
  • 15
  • 145
  • 224
  • As an alternative to this method, will `namespace FILE { ... }` and `class FILE { ... }` (side-by-side, not one inside another) conflict? – Elan Hickler Dec 01 '15 at 19:50
  • yes, you cannot have 2 identifiers declaring 2 different types of symbols at the same scope – bolov Dec 01 '15 at 20:06
1

If you want to provide rename in your public interface, you'll need to write wrappers:

#include <boost/filesystem.hpp>

class File {

public:
    static void rename(const boost::filesystem::path& from, const boost::filesystem::path& to) {
        boost::filesystem::rename(from, to);
    }
    static void rename(const boost::filesystem::path& from, const boost::filesystem::path& to, boost::system::error_code& ec) {
        boost::filesystem::rename(from, to, ec);
    }
};

or, if you also want to provide the relevant types as a convenience:

#include <boost/filesystem.hpp>

class File {

    using path = boost::filesystem::path;
    using error_code = boost::system::error_code;

public:
    static void rename(const path& from, const path& to) {
        boost::filesystem::rename(from, to);
    }
    static void rename(const path& from, const path& to, error_code& ec) {
        boost::filesystem::rename(from, to, ec);
    }
};
Toby Speight
  • 27,591
  • 48
  • 66
  • 103