【问题标题】:Use Boost to ensure template argument inherits from some class使用 Boost 确保模板参数继承自某个类
【发布时间】:2012-05-19 01:31:57
【问题描述】:

我刚刚注意到我的代码经常重复这种结构:

if( someErrorHappened ){
        string errorMsg = "Falcon Punch!";
        ::GetErrorLoggerInstance()->Log( LOG_TYPE_ERROR, "class", "method", errorMsg );
        throw SomeCustomException( errorMsg );
}

我想我可以编写一个模板函数,这样我就可以用这样的单行替换所有这些:

LogAndThrowIfError<SomeCustomException>( someErrorHappened, "class", "method", "Falcon Punch!" );

我可以用我的基本模板知识做到这一点。我的问题是,如果模板参数是一个不从特定类继承的类,我可以使用 Boost 来确保出现编译错误吗? (即我只想让这个函数用于我的自定义异常)。有点像 C# 的 where 泛型关键字。

这似乎有些牵强,但我需要强制执行,因为我们的应用程序具有托管和非托管代码,并且我们的自定义本机异常映射到自定义托管异常,这就是为什么这应该只与我们的异常一起使用。

我在 Visual Studio 2010 中工作,所以我没有所有花哨的 C++11 东西,只有一些(移动语义是最有趣的)。

【问题讨论】:

标签: c++ visual-studio-2010 templates boost


【解决方案1】:

试试

 BOOST_STATIC_ASSERT(( boost::type_traits::is_base_of< ExceptionBaseClass, T >::value ));

它在内部执行与@Zolyomi 在他的答案中发布的相同的检查。

【讨论】:

    【解决方案2】:

    实际上,您不需要 Boost 或任何花哨的库来执行此操作,尽管您可以根据需要使用它们。最简单的方法是做类似的事情

    template<typename T>
    void LogAndThrowIfError(...options...)
    {
        static ExceptionBaseClass *CheckBaseClass_WriteYourErrorMessageHere = static_cast<T*>(null);
        ... your logging code here ...
    }
    

    模板每次实例化一个新的类型T,它都会检查一次T*是否可以转换为ExceptionBaseClass*,这基本上相当于T是从ExceptionBaseClass派生的。

    请注意,如果检查失败,错误消息可能不是很直接,如果您不介意依赖 Boost 或其他库,则可能会提供更好的错误消息。

    【讨论】:

    • +1:很高兴知道这一点。我已经在使用 Boost,所以如果它提供了更好的错误信息,我会坚持使用它。
    • 我并不是说它会给出更好的错误信息,尽管可能是这样,但我从未尝试过。 ;-) 我只想提一下我可能遇到的缺点。
    猜你喜欢
    • 2014-02-09
    • 2018-05-23
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多