繁体   English   中英

C ++模板分支

[英]C++ Template Branching

我有一个有趣的例子,试图在模板函数中有分支,其中路径依赖于模板类型实现的接口。 然后该分支确定返回值的构造函数。 我不确定这种分支是否可行。 可以选择将功能拆分为两个不同的功能,并让用户调用与所需分支对应的功能。

我的问题是双重的:

如何根据接口实现执行if语句?

如何在未实现接口时获取编译功能? 例如, int没有带有两个参数的构造函数。

template<typename T>
T GetObject()
{
    // If T implements interface, call interface constructor
    if(typeid(T) implements inteface IInterface) // How can this be done?
        return T(1, 2);

    // If T does not implement the interface, call parameterless constructor
    else
        return T();
}

正如您可以轻易推断的那样,您的代码无法正常工作(即使我希望它能够实现),因为无论您在if语句中添加了什么内容,都必须编译每一行 - 即使稍后某些行将在优化期间被删除。 即使你有正确的行:

if(typeid(T) implements inteface IInterface)
    return T(1,2); // <---

第二行仍然会为int编译,这是不好的。

你想要的是SFINAE:替换失败不是一个错误。 基本上,你有意写一个无法编译的声明 ,但只要有一个可编译的可用重载就足够了! 所以为此,我们只是利用了一些类型的特征和魔力,但非常简单, enable_if

// this overload will only exist if T is-a IInterface
template<typename T>
typename std::enable_if<
    std::is_base_of<IInterface, T>::value,
    T
>::type
GetObject() {
    return T(1,2);
}

// this overload will only exist if T is NOT an IInterface
template<typename T>
typename std::enable_if<
    !std::is_base_of<IInterface, T>::value,
    T
>::type
GetObject() {
    return -1;
}

// explicit for int - put this *last*
// due to complications with specialization
template <>
int GetObject() {
    return 0;
}

虽然给出了Herb Sutter关于函数特化的文章 ,但最好使用重载:

template <typename T> struct empty_ { };

template <typename T>
T GetObject() { return GetObjectImpl(empty_<T>{} ); }

// the int version: overload, not specialization
int GetObjectImpl( empty_<int> ) { 
    return 0;
}

// the other two versions are the same as before
template <typename T>
typename std::enable_if<... same as before ...>::type
GetObjectImpl(empty_<T> ) {
    return T(1,2);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM