Я хочу получить доступ к методу String :: Format из моей кодовой базы C++. Для этого я мог бы просто создать функцию:
template<typename... ArgTypes>
void FormatAString(CString& format, ArgTypes... args)
{
String^ toFormat = gcnew String(format);
format = String::Format(toFormat, args...);
}
Моя проблема в том, что не каждый файл в моей кодовой базе является интерфейсом командной строки, и я хочу вызвать этот метод из неуправляемой части. Для этого я обычно объявляю методы в файле заголовка и реализую их в управляемом файле .cpp.
Поскольку я использую здесь пакет параметров, я не могу отделить реализацию метода от объявления. Итак, решение или, лучше сказать, обходной путь, который я придумал, заключается в следующем:
//My header file
template<typename... ArgTypes>
void FormatAString(CString& format, ArgTypes... args);
В заголовочном файле я объявил метод, как обычно.
// My cpp file
template<typename... ArgTypes>
void FormatAString(CString& format, ArgTypes... args)
{
String^ toFormat = gcnew String(format);
format = String::Format(toFormat, args...);
}
void tempMethod()
{
int i;
FormatAString(CString("Hello"), i);
FormatAString(CString("Hello"), i, i);
FormatAString(CString("Hello"), i, i, i);
FormatAString(CString("Hello"), i, i, i, i);
FormatAString(CString("Hello"), i, i, i, i, i);
FormatAString(CString("Hello"), i, i, i, i, i, i);
}
Чтобы компоновщик работал, я создал временный метод (я узнал, что это возможно здесь: https://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp)
Проблема в том, что мне пришлось бы добавить все возможные комбинации типов, которые я позже захочу использовать, в tempMethod, что не является постоянным решением.
Поэтому, если я хочу вызвать FormatAString(CString("Hello {0}", "World"); откуда-то в моем коде, мне придется добавить что-то вроде этого в tempMethod:
const char* c;
FormatAString(CString("Hello"), c);
Есть ли лучший способ отделить объявление от реализации? Это мой первый вопрос по SO, надеюсь, информации достаточно.





Попробуй это:
#include <atlstr.h>
#pragma managed(push, on)
using namespace System;
template<typename... ArgTypes>
void FormatAString(CString& format, ArgTypes... args)
{
String^ toFormat = gcnew String(format);
format = String::Format(toFormat, args...);
}
#pragma managed(pop)
#pragma managed(off)
void test()
{
CString a("{0} {1} {2} {0} ");
FormatAString(a, 1, 10.2, 10.0f);
}
Однако, если вы передадите строковый литерал, вы получите ошибку, потому что компилятор (vs2017) жалуется, что не может преобразовать cli :: array ...
Плохая идея по-разному. Вы не можете обойти фундаментальное ограничение, заключающееся в том, что шаблоны не имеют внешней связи, реализация должна отображаться в файле заголовка. И вы не можете обойти фундаментальное требование, согласно которому использование управляемого кода, такого как String :: Format (), требует компиляции с / clr. Это никуда не денется.