C ++模板可以确定声明/定义的实例是否是常量?

时间:2014-01-27 17:11:36

标签: c++ templates c++11

对于给定的模板,例如std::string,模板可以检测声明/定义的string实例是否为常量。 (注意:我不是在询问模板参数。)

std::string mutable_string("a string that may possibly be changed");

const std::string immutable_string("a string that will not change);

如果可以,模板可以为提供给构造函数的字符串文字准确分配堆存储量。此外,可以省略非const,非ctor / dtor方法的代码生成(除非某些翻译单元定义了非const字符串)。

我希望在语义上类似于:

is_constant<std::string>(*this)::value

是否可以将实例的类型与剥离的const限定符进行比较?

更新/澄清:扩展std::string示例,const std::string的模板专精化是否能够将检查员声明为constexpr(例如size() },capacity()

2 个答案:

答案 0 :(得分:5)

如果我说对了你的话:

#include <iostream>

template <typename T>
inline constexpr bool is_constant(T&) {
    return false;
}

template <typename T>
inline constexpr bool is_constant(const T&) {
    return true;
}

template <bool Value>
void print() {
    std::cout << (Value ? "true " : "false ");
}

struct X {
    void a() { print<is_constant(*this)>(); }
    void b() const { print<is_constant(*this)>(); }
};

int main() {
    X x;
    // false
    x.a();
    // true
    x.b();
    std::cout << '\n';
    return 0;
}

但是,如果你想检测一个对象是否是const限定的,那是不可能的 - 构造函数永远不会是const。

答案 1 :(得分:1)

不,您无法检测正在构建的对象是否会被标记为const。如果你关心的是提供准确的内存分配,那就行了,没关系。如果字符串不是const,那么它将在需要时根据需要增长。

关于代码生成,模板的成员通常是按需生成的,因此如果不使用它们,它们将不会生成,因此没有胜利。 通常是因为在显式实例化中不是这种情况,并且在这种特殊情况下,由于性能原因(编译器时间),您的实现可能正在进行显式实例化,因为{{1}的常见实例化(basic_stringchar)供应商可以在链接库中以二进制形式提供实现。