【发布时间】:2013-02-19 17:04:04
【问题描述】:
我有以下示例代码,它使用字符串文字作为模板参数,以便基类模板可以访问该字符串。
代码编译,但我收到一个我不完全理解的警告:
警告:‘ns::bar::type’有一个基数‘ns::base' 其类型使用匿名命名空间 [由 默认]
下面的工作示例代码:
// "test.h"
#pragma once
namespace ns
{
template <char const* str>
struct base
{
const char *name() const { return str; }
};
namespace bar
{
static constexpr char name[] = "bar";
struct type : base<name> {}; // <-- this line here
}
}
// main.cpp
#include <iostream>
#include "test.h"
int main()
{
ns::bar::type f;
std::cout << f.name() << std::endl;
return 0;
}
所以我的问题是:
- 此警告是什么意思?
- 以我在这里所做的方式将字符串文字作为模板参数传递是否安全?
(注意这是 gcc 4.7.2)
【问题讨论】:
-
#2 很容易回答:是的,它是安全的,只要您始终使用
ns::bar::name作为模板参数;另一个带有内容“bar”的单独字符串可能不在内存中的同一位置(并且肯定不会关闭优化,例如在调试构建期间),这将导致单独的base<>实例化(尽管是一个其行为方式相同)。 -
所以我可能会使用
#pragma来禁用此特定实例化的警告,并且仍然感到温暖和快乐? (如果确实存在一个这样的编译指示 - 粗略的谷歌似乎无法找到它) -
不知道 ;-) 这个警告对我来说也是新的。我只回答了你问题的后半部分。你用的是什么编译器? (啊,没关系,我看到它是 gcc 4.7.2)。我无法使用 gcc 4.7.2 重现警告。而且我没有看到你提到的 anonymous 命名空间?
-
嗯——考虑到在头文件中定义了内部链接的类型在包含头文件的每个文件中都是不同的类型,这样做真的会出错吗?也许#2毕竟不安全?
-
@Cameron - 您是否将代码拆分为 2 个单独的文件?上半场必须是头球。如果您将其全部编译到 1 个文件中,那么您不会收到警告 - 我猜是因为现在没有内部链接问题?