3

我正在尝试获取一些最初使用 GCC 构建的代码以使用 MSVC 进行编译,并且在代码中遇到了回调包装类的问题。我提取了以下代码的关键部分:

template <typename T_func>
struct internal_parameter_resolver;

template <typename R>
struct internal_parameter_resolver<R()> {
    typedef R(*type)();
};

template <typename R, typename P1>
struct internal_parameter_resolver<R(P1)> {
    typedef R(*type)(P1);
};

template <typename T_func, typename internal_parameter_resolver<T_func>::type func>
void bind() {
    // Create and return instance of class Callback...
}

double func1() { return 0.5; }
int func2(double i) { return 0; }

int main() {
    bind<double(), &func1>();    // (Line 23)
    bind<int(double), &func2>(); // (Line 24)

    return 0;
}

虽然这在 GCC 下编译得很好,但 MSVC 2010 给出了以下错误消息:

1>c:\users\public\documents\projects\_test\_test\main.cpp(23): error C2975: 'func' : invalid template argument for 'bind', expected compile-time constant expression
1>          c:\users\public\documents\projects\_test\_test\main.cpp(14) : see declaration of 'func'
1>c:\users\public\documents\projects\_test\_test\main.cpp(24): error C2975: 'func' : invalid template argument for 'bind', expected compile-time constant expression
1>          c:\users\public\documents\projects\_test\_test\main.cpp(14) : see declaration of 'func'

有人知道为什么 MSVC 认为这些函数指针不是编译时常量吗?还是代码中其他地方的问题(即不是第 23 和 24 行)?如果它是编译器中的错误,我会欢迎任何有关可能解决方法的建议。

谢谢!

4

2 回答 2

2
template <typename T_func, T_func* >
void bind() {
    // Create and return instance of class Callback...
}

Visual C++ 不擅长解析间接类型定义,但它对更具体的类型很满意,就像上面一样。

上面显示了如何使用 Visual C++ 处理您遇到的直接问题。

但是,更好的设计是使用自动模板参数推导:

template <typename T_func >
void bind( T_func const func ) {
    // Create and return instance of class Callback...
}

double func1() { return 0.5; }
int func2(double i) { return 0; }

int main() {
    bind( func1 );      // (Line 23)
    bind( func2 );      // (Line 24)
}

如果需要,您可以从 获取函数结果类型std::function,依此类推。

于 2012-08-11T21:35:56.540 回答
1

我看不出有任何理由将func1func2作为非类型模板参数传递。

最好将它们作为参数(而不是模板参数)传递,并让internal_parameter_resolvertrait 推断其类型:

template <typename T_func>
struct internal_parameter_resolver;

template <typename R>
struct internal_parameter_resolver<R()> {
    typedef R(*type)();
};

template <typename R, typename P1>
struct internal_parameter_resolver<R(P1)> {
    typedef R(*type)(P1);
};

template <typename T_func>
void bind(typename internal_parameter_resolver<T_func>::type func) {
    // Create and return instance of class Callback...
}

double func1() { return 0.5; }
int func2(double i) { return 0; }

int main() {
    bind<double()>(func1);    // (Line 23)
    bind<int(double)>(func2); // (Line 24)

    return 0;
}

我手头没有VC,但应该可以编译。

于 2012-08-11T21:36:11.397 回答