athos athos - 1 month ago 28
C++ Question

C2660: _splitpath_s fails with std::array error in Visual Studio 2013

Visual Studio 2013 is a bit weird on language array that in global function it's allowed to initialize one as

char result[100] = { 0 };
, but not if it's a class's member -- referring to
Workaround for error C2536: cannot specify explicit initializer for arrays in Visual Studio 2013, for
int m_array[3];
inside
class A
,
A() :m_array{ 0, 1, 2 } {}
fails with Error C2536: "'A::A::m_array' : cannot specify explicit initializer for arrays".

In the same post a work-around is suggested, using
std::array<int, 3> m_array;
instead and initilzie with
A() : m_array ({ 0, 1, 2 }) {}

, IDE red underlined "0" hinting "Error: braces cannot be omitted for this subobject initializer." but can compile.

Even better, one comments suggested use an extra pair of braces
A() : m_array ({ { 0, 1, 2 } }) {}
, and now all smooth!

To pass a
std::array
to a function requiring a
char *
parameter, std::array over c style array suggest use
my_array.data()
where
my_array
is a
std::array
.

Now I met a problem with
_spitpath_s
:

The traditional
char *
style compiles
_splitpath_s(fullpathfilename, drive, dir, name, ext)
where the parameters are all
char
arrays; but using
std::array
will trigger error C2660:

class B2
{
public:
const int MAX_LEN = 200;
std::array<char, 200> drive, dir, name, ext;
B2() :drive({ { 0 } }), dir({ { 0 } }), name({ { 0 } }), ext({ { 0 } }) {}
void split(const char * fullpathfilename) {
_splitpath_s(fullpathfilename, drive.data(), dir.data(), name.data(), ext.data()); //error C2660: '_splitpath_s' : function does not take 5 arguments
}
};


.

Why
_splitpath_s
fails here? This is an old C style function, defined in
stdlib.h
, if there's a work-around in C++, also acceptable.

Answer

The 5 parameter version of _splitpath_s is a template function, expecting a character pointer for the input path, and C-style character arrays for the other 4. Since you are passing in C++ array objects, the template is not generated and, due to SFINAE it is not available so there is no function that takes 5 parameters.

To use it you'll have to use the 9 parameter version, where you pass in the input addresses and buffer sizes.