【问题标题】:Conditional template条件模板
【发布时间】:2020-01-24 17:07:04
【问题描述】:

我有一个带模板的课程 在这个类里面有一个变量 T * Variable;和变量字符串str;并且有部分代码的功能:

if(std::is_same<T, string>::value){
    *Variable = str;
    return 0;
}

当然,尽管由于之前的条件,上述赋值不会对不同的变量起作用,但编译器会在编译时抱怨。 我正在考虑编写带有两个模板参数的条件模板函数来代替上面的赋值:

Assign(Variable, &str);

课前:

template <typename T, typename U>
conditional <T, U> void Assign(T* to, U* from){
    ;
}
conditional <string, string> void Assign(T* to, U* from){
    *to = *from;
}

所以编译器会为我需要的字符串选择专门的一个。如何制定这个?这可以仅针对变量类型制定还是我需要第三个参数?或者,函数内部的主要代码可能存在某种模板条件?

【问题讨论】:

  • 你能用C++17吗? if constexpr
  • 到目前为止我应该兼容 c++ 11, 14, 17
  • 在我看来像xy problem。为什么需要根据类型有条件地赋值?会不会重载这个sn-p来自的函数?

标签: c++ class templates


【解决方案1】:

只使用模板特化:

template<typename T>
class Foo {
    T * Variable;

public:
    explicit Foo(T *p) : Variable{p}
    {}

    void Assign(const std::string& str) {
        std::cout << str << " No op\n";
    }
};

template<>
void Foo<std::string>::Assign(const std::string& str) {
    *Variable = str;
}

https://wandbox.org/permlink/Oi1bl8LCQQQ2LyJC

这适用于相当旧的 C++ 版本(至少 C++03)。

【讨论】:

  • 所以,如果我理解正确:你在这里有你使用模板重载字符串的函数继承?你是在构造函数中使用 p 初始化变量吗?嗯,所以这个重载的函数应该在 Foo 类之外重载。我需要在这个类中使用它。
  • @Gen0me 这不是继承,而是template specialization。方法没有重载,但是模板参数std::string的实现改了。
  • 我解决了这个问题,但我还是很好奇:这个方法是否适用于类内的函数调用
【解决方案2】:

如果您可以访问 C++17,那么只需使用 if constexpr:

if constexpr (std::is_same<T, string>::value) {
    *Variable = str;
    return 0;
}

【讨论】:

  • 我收到错误:在 'constexpr' 之前预期的 '(' 我已经更新到 c++ 17 编译
  • @Gen0me 当 C++17 被禁用或不受支持时,通常会出现这种错误。你的编译器版本是什么,你的标志是什么?
  • TDM64 g++, -fpermissive
  • @Gen0me C++17 使用-std=c++17 标志启用。为此,您需要 GCC 7 或更高版本。我不确定你现在有什么版本。
  • 另外,你应该尝试摆脱-fpemissive。那面旗帜不是你的朋友。我会尝试仅在需要的翻译单元中启用它。
【解决方案3】:

所以我在我的课之前用模板和模板专业化编写了分配函数

template<typename T, typename U>
void Assign(T* to, U* from){
    ;
}
template<>
void Assign(string* to, string* from){
    *to = *from;
}

我改变了行 *Variable = str;进入:

Assign(Variable, &str);

这是一个对我有帮助的话题: Templated Functions.. ERROR: template-id does not match any template declaration

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-12
    • 2015-05-25
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多