我正在为C ++库编写一个简单的包装器。我有以下类型描述成功的结果或错误:
template<typename T>
struct Result
{
T value;
const char* error;
static Result<T> FromFunction(std::function<T()> function)
{
Result<T> result = {};
try
{
result.value = function();
}
catch( cv::Exception& e )
{
const char* err_msg = e.what();
auto len = std::strlen(err_msg);
auto retained_err = new char[len + 1];
std::strcpy(retained_err, err_msg);
result.error = retained_err;
}
return result;
}
};
我用它:
extern "C" {
Result<double> foo() {
...
return result;
}
}
它适用于GCC (此函数被调用并返回正确的结果),但是,由于模板参数作为函数返回类型,msvc非常沮丧:
error C2526: 'foo': C linkage function cannot return C++ class 'CResult<double>'
我写了以下解决方法,它似乎有效,但我对公共界面中的void*
不确定:
void* foo() { {
return &result;
}
这被认为是一种不好的做法吗?因为我想遵循DRY原则,不要写很多或包装,如ResultDouble,ResultInt等。
答案 0 :(得分:2)
不确定MSVC有什么问题,但是如果你使用输出参数似乎很高兴(至少在MSVC19-RTW,godbolt上可用的版本)
extern "C"
{
void foo( Result<double> * res ) {
//....
*res = {};
}
}
答案 1 :(得分:0)
C没有模板,所以你的编译器是正确的抱怨/错误。
你是一个奇怪的用例,因为技术上你的函数foo有一个完全定义的类型,你可以用C链接导出它(比如在库中)。但是,任何读取该代码段的C编译器都会呕吐,因为C编译器不应该知道模板是什么。