如何在c++中使用模板类中的模板参数有条件地实现模板函数

wfsdck30  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(144)

我知道这个问题听起来有点混乱,但请耐心听我说,因为我希望这个例子至少能给予你了解我在问什么。

如果您对此问题有更好的名称,请随时告知我,我将立即更改名称

我们开始吧!
假设我有一个类

template <size_t size_of_allocated_memory_in_bytes> class malloc_ptr

在其中我有一个方法

template <typename cast_type, bool should_use_c_cast> cast_type cast();

这是整个类;

template <size_t size_of_allocated_memory_in_bytes>
class malloc_ptr
{
private:
    void* ptr;

public:
    malloc_ptr()
        : ptr(malloc(size_of_allocated_memory_in_bytes)) {}

    template <typename cast_type , bool should_use_c_cast>
    cast_type cast();

    ~malloc_ptr() noexcept
        { free(ptr); }
};

我知道我可以像这样实现这个函数[在https://stackoverflow.com/questions/27283261/template-function-in-a-templated-class的帮助下]

template<size_t size_of_allocated_memory_in_bytes> 
template<class cast_type, bool should_use_c_cast> 
cast_type malloc_ptr<size_of_allocated_memory_in_bytes>::cast()
{
    return reinterpret_cast<cast_type>(ptr);
}

然而,我只希望函数在should_use_c_cast == true时实现,但我不知道如何实现。
我希望大家能在这方面提供帮助。此外,任何帮助将不胜感激。并提前感谢您!

xhv8bpkk

xhv8bpkk1#

如果你想要一个true的实现,一个false的实现,你需要C++17的if constexpr,因为你不能部分地专门化一个函数模板。

template<size_t size> 
template<class cast_type, bool should_use_c_cast> 
cast_type malloc_ptr<size>::cast()
{
    if constexpr (should_use_c_cast) {
        return reinterpret_cast<cast_type>(ptr);
    } else {
        // false case here
    }
}

然而,你的should_use_c_cast用例有未定义的行为,所以我建议你甚至不需要should_use_c_cast,而是使用placement new.你使用malloc也是可疑的,因为对象有对齐要求,所以如果malloc返回一个未对齐的指针,你的程序将再次有未定义的行为.

template <size_t size, size_t align = size>
class malloc_ptr
{
private:
    void* ptr;

public:
    malloc_ptr()
        : ptr(aligned_alloc(align, size)) {}

    template <typename cast_type>
    cast_type * cast();

    ~malloc_ptr() noexcept
        { free(ptr); }
};

template<size_t size_of_allocated_memory_in_bytes> 
template<class cast_type> 
cast_type * malloc_ptr<size_of_allocated_memory_in_bytes>::cast()
{
    return new (ptr) cast_type;
}
uqzxnwby

uqzxnwby2#

一种方法是使用enable_if,如下所示:

template <size_t size_of_allocated_memory_in_bytes>
class malloc_ptr
{
private:

public:
    
    template <typename cast_type , bool should_use_c_cast>
//-------------------vvvvvvvvvvvvvvvvv--------------------->condition here
    std::enable_if_t<should_use_c_cast,cast_type> cast();

};

在C++20中,您可以使用requires

template <size_t size_of_allocated_memory_in_bytes>
class malloc_ptr
{
private:

public:
    
    template <typename cast_type , bool should_use_c_cast>
    cast_type cast() requires(should_use_c_cast);

};

相关问题